4

思い出させるために(ウィキから):

インターフェイス分離の原則(ISP) は、クライアントが使用しない方法に依存することを強制されるべきではないと述べています。

そして今、私の例を見てください。

これが私の可変エンティティです。どこかから編集され、読み取り専用インターフェイスを介して変更を通知できます。

interface ICounter
{
    event Action<int> NewNumber;
}

class Counter : ICounter
{
    public event Action<int> NewNumber;

    int number = 0;
    public void IncrementAndSend(int x)
    {
        number += x;
        if (NewNumber != null) NewNumber(number);
    }
}

そして、これを使用するトランスポート層のクラスを次に示します。インジェクションの 2 つのバリアント (Attach_1およびAttach_2) と、以下の私の仮定を見てください。

class OneToManyRouter
{
    IEnumerable<Counter> _destinations;

    public OneToManyRouter(IEnumerable<Counter> destinations)
    {
        _destinations = destinations;
    }

    // 1         
    public void Attach_1(ICounter source)
    {
        source.NewNumber += (n) =>
        {
            foreach (var dest in _destinations) dest.IncrementAndSend(n);
        };
    }

    // 2 
    public void Attach_2(Counter source)
    {
        source.NewNumber += (n) =>
        {
            foreach (var dest in _destinations) dest.IncrementAndSend(n);
        };
    }
}
  1. ISP は実際のオブジェクトに関するものです。着信パラメーターへの「過剰な」参照を使用してはなりません。
  2. ISP はクラスに関するものです。クラスがすでにどこかで完全なインターフェースを使用している場合、特定のメソッドで参照型を制限する必要はありません。 ICounterこの例ではインターフェイスが過剰です。
  3. このアーキテクチャは、SOLID 原則の観点からは完全に間違っています (では、なぜでしょうか?)。
4

2 に答える 2

2

ISP はクラスでもオブジェクトでもなく、厳密にはインターフェース、特にインターフェース設計に関するものです。この原則は、ユーザーが残りを空の関数として実装するためにこれらのメソッドのサブセットのみを必要とすることを避けるために、単一のインターフェースで半関連メソッドのグループ化を思いとどまらせることを目的としています ( a をスローするNotImplementedExceptionか、文字通り空のままにするかのいずれか{ })。したがって、より一貫性のあるクラスを実装し、インターフェイスをより効果的に使用することが容易になります。

あなたの例では、ISPの概念に直接関係しない方法で、Counterクラスとインターフェースの両方を組み合わせています。ICounter

  1. ISP は実際のオブジェクトに関するものです。着信パラメーターへの「過剰な」参照を使用してはなりません。

これは部分的に真実です (「過剰」の概念を正しく解釈すれば)。ただし、前述したように、ISP は実際のオブジェクトと対話する方法ではなく、有用なインターフェイスを定義する方法についてです。

  1. ISP はクラスに関するものです。クラスがすでにどこかで完全なインターフェースを使用している場合、特定のメソッドで参照型を制限する必要はありません。この例では ICounter インターフェイスが過剰です。

これは正しくありません。インターフェイスではなく具象クラスに依存関係を作成する場合、クラスがインターフェイスを実装するという事実は何の意味もありません。インターフェイスは、コンポーネントが将来変更される可能性のある特定の実装ではなく、コントラクトに依存するようにすることで、プログラムのさまざまな部分の分離を提供することを忘れないでください。具体的なクラスを使用すると、この利点が失われます。繰り返しますが、これは ISP の概念に完全に関連しているわけではありません。

  1. このアーキテクチャは、SOLID 原則の観点からは完全に間違っています (では、なぜでしょうか?)。

SOLID の原則に重点を置いたアーキテクチャの観点から、ICounterではなくに依存し、インターフェイス定義の一部としてCounter含めることをお勧めします。IncrementAndSend

于 2013-07-19T21:12:22.760 に答える
0

インターフェースに IncrementAndSend メソッドを追加して、クラス OneToManyRouter を IEnumerable<ICounter> に依存させると良いと思います。私の意見では、NewNumber イベント アクションと IncrementAndSend メソッドは厳密に関連しているため、これは ISP 違反ではありません。それがあなたを助けることを願っています。

于 2013-07-19T18:46:39.153 に答える