2

この状況は何度も起こりましたが、解決方法がわかりません。

インターフェイス分離の原則は、一部のインターフェイス実装がその機能を使用しない状況を防ぐために作成されました-それは明らかです。インターフェースのリストがあり、それらを使って何かをしたいという状況がよくあります。ISP なしの例を見てみましょう:

  public interface IPerson
    {
           void Run();
           void Eat();
    }

public class AbcPerson : IPerson
{
       void Run(){};
       void Eat(){};
}

public class XyzPerson : IPerson
{
       void Run(){};
       void Eat(){};
}

List<IPerson> People {get;set;}

そして、すべての人と走りたい。

      foreach(var person in People)
      {
         person.Run();
      }

今はみんなと一緒に食べたいです。

          foreach(var person in People)
          {
             person.Eat();
          }

ISP を使用する場合は、コードを次のように変更する必要があります。

        public interface IRunnable
        {
               void Run();
        }
        public interface IEatable
        {
               void Eat();
        }

    public class AbcPerson : IRunnable,IEatable
    {
           void Run(){};
           void Eat(){};
    }

    public class XyzPerson : IRunnable,IEatable
    {
           void Run(){};
           void Eat(){};
    }

人のリストはどのように作成すればよいですか? Runable と Eatable の 2 つのリストを作成してオブジェクトを追加する必要がありますか (醜い)、または 2 番目のアプローチ - 1 つのリストを作成し、可能であればそれらをキャストする必要がありますか (醜い)? それを行うための最良の規則が何であるかはわかりません。

この例は、私が想像できる最良の例ではないかもしれませんが、私の言いたいことを理解していただければ幸いです。

編集: インターフェイスとクラス、およびプリンシパル名を変更しました。

4

3 に答える 3

2

ランニング食事はどちらも「人間であること」の責任であると主張できるため、IPerson インターフェイスを維持することは合理的です。

IRunnable と Ieatable のインターフェイスを別々に定義することに価値があると感じた場合は、それらを使用して IPerson インターフェイスを定義できます。

public interface IPerson : IRunnable, IEatable {}

これは、質問の単一の責任の側面から少し離れていますが、これはジレンマの一部である可能性があると感じています。物事の「実行可能な」側面のみを気にする他のコードがある場合は、IEnumerable<IRunnable>パラメータを取るメソッド。.NET 4 で導入された共分散規則により、List<IPerson>オブジェクトであるIEnumerable<IRunnable>ため、キャストせずに単純に渡すことができます。

void DoSomethingWithRunnables(IEnumerable<IRunnable> runnables)
{
    ...
    foreach (var item in runnables)
    {
        item.Run();
    }
    ...
}
于 2014-06-10T13:48:35.707 に答える