27

インターフェイス分離の原則は、単一責任の原則の代わりにすぎませんか?

クラスが SRP を満たす場合、複数のインターフェイスを抽出する必要はないと思います。

したがって、ISP は、何らかの理由で SRP を壊さなければならない場合の解決策のように見えます。

私は正しいですか?

4

3 に答える 3

33

いいえ。ハードドライブなどにデータを永続化する役割を持つクラスの例を考えてみましょう。クラスを読み取り部分と書き込み部分に分割しても、実際には意味がありません。ただし、クラスをデータの読み取りのみに使用するクライアント、データの書き込みのみに使用するクライアント、および両方を行うクライアントがあります。ここで 3 つの異なるインターフェイスを使用して ISP を適用すると、優れたソリューションになります。

于 2011-11-11T19:42:15.910 に答える
19

クラスが SRP を満たす場合、複数のインターフェイスを抽出する必要はないと思います。

単一責任の原則とは、クラス (またはメソッド) に複数の変更理由があってはならないというものです (つまり、それぞれが 1 つの機能のみを担当します)。これを尊重するために、システムの開発に合わせて新しいクラスを作成する必要があります。

たとえば、Carクラスから始めて、ギアを変更する機能が必要であることがわかった場合、これをGearboxクラスに抽出します。これは、ギア チェンジの背後にあるメカニズムを変更しても、親Carクラスを変更する必要がないことを意味します。車にパワー ステアリングを追加する場合は、これを独自のクラスに再度抽出します。ラジオは別のクラスになります。

この抽象化のカスケードは、Carクラス全体で発生します。それ自体から下に移動するとCar、各クラスで詳細が増加することがわかります。たとえば、CarクラスにはchangeGear()、ユーザーがギアを選択できるようにするメソッドがある場合がありますが、Gearboxクラスは作成の核心に注意を払います。これが発生します (例: クラッチを踏む、現在のギアを外す、新しいギアを選択するなど)。

ただし、OO 設計ではGearbox、エンドユーザーに詳細を公開したくありません。内部がどのように機能するかを知る必要なく、高いレベルの抽象化でシステムとやり取りしてもらいたいのです。また、ユーザーがコードをリファクタリングしなくても将来的に変更できるように、これらの内部をリングフェンスしたいと考えています (これが、privateまたはとしてフラグを立てる理由protectedです)。

Carこのため、ユーザーがクラス自体を介してのみ車と対話できるようにします。ここで、インターフェイス分離の原則の出番です。SRP は、クラスがそのサブコンポーネントを別のクラスに委譲することを保証しますが、すべてのメソッドはクラス自体を通じて呼び出されます。ISPは、これらすべてを 1 つのインターフェイスにまとめるのではなく、論理的な区別を作成し、関連する機能のために複数のインターフェイスを公開することを保証します。CarpublicCar

于 2013-04-21T22:15:06.493 に答える
1

いいえ。

クラスは複数のインターフェイスを実装できますが、クラスにのみ適用可能なメソッドを実装する必要があります。

のような 10 以上の異なる機能があるとしますClimb, Think, Learn, Apply。クラスDogは 2 つの機能を持つCatことができ、クラスは 2 つの機能を持つことができ、クラスManは 6 つの機能を持つことができます。それぞれのクラスで適用可能な機能のみを実装することは理にかなっています。

このコードを見てください。

public class ISRDemo{
    public static void main(String args[]){

        Dog dog = new Dog("Jack",16);
        System.out.println(dog);

        Learn dl = dog;
        dl.learn();
        ProtectOwner p = dog;
        p.protectOwner();

        Cat cat = new Cat("Joe",20);
        System.out.println(cat);
        Climb c = cat;
        c.climb();
        Remember r = cat;
        cat.doRemember();       

        Man man = new Man("Ravindra",40);   
        System.out.println(man);
        Think t = man;
        t.think();
        Learn l = man;
        l.learn();
        Apply a = man;
        a.apply();
        PlaySports pm = man;
        pm.playSports();
        Remember rm = man;
        rm.doRemember();

    }
}

class Dog implements Learn,ProtectOwner{
    private String name;
    private int age;
    public Dog(String name,int age){
        this.name = name;
        this.age = age;
    }

    public void learn(){
        System.out.println(this.getClass().getSimpleName()+ " can learn");
    }
    public void protectOwner(){
        System.out.println(this.getClass().getSimpleName()+ " can protect owner");
    }
    public String toString(){
        return "Dog :"+name+":Age:"+age;
    }
}
class Cat implements Climb,Remember {
    private String name;
    private int age;
    public Cat(String name,int age){
        this.name = name;
        this.age = age;
    }
    public void climb(){
        System.out.println(this.getClass().getSimpleName()+ " can climb");
    }
    public void doRemember(){
        System.out.println(this.getClass().getSimpleName()+ " can remember");
    }
    public String toString(){
        return "Cat :"+name+":Age:"+age;
    }
}
interface ProtectOwner {
    public void protectOwner();
}
interface Remember{
    public void doRemember();
}
interface Climb{
    public void climb();
}
interface Think {
    public void think();
}
interface Learn {
    public void learn();
}
interface Apply{
    public void apply();
}
interface PlaySports{
    public void playSports();
}

class Man implements Think,Learn,Apply,PlaySports,Remember{
    String name;
    int age;

    public Man(String name,int age){
        this.name = name;
        this.age = age;
    }
    public void think(){
        System.out.println(this.getClass().getSimpleName() + " can think");
    }
    public void learn(){
        System.out.println(this.getClass().getSimpleName() + " can learn");
    }
    public void apply(){
        System.out.println(this.getClass().getSimpleName() + " can apply");
    }
    public void playSports(){
        System.out.println(this.getClass().getSimpleName() + " can play sports");
    }
    public void doRemember(){
        System.out.println(this.getClass().getSimpleName() + " can remember");
    }
    public String toString(){
        return "Man :"+name+":Age:"+age;
    }
}

出力:

java ISRDemo
Dog :Jack:Age:16
Dog can learn
Dog can protect owner
Cat :Joe:Age:20
Cat can climb
Cat can remember
Man :Ravindra:Age:40
Man can think
Man can learn
Man can apply
Man can play sports
Man can remember

上記の例では、インターフェイスの分離により、すべての機能をファット インターフェイスで宣言するのではなく、10 個のインターフェイスで 10 個の機能を定義することが推奨されます。ただし、単一の責任基準を満たすために異なるクラスが必要であるという意味ではありません

Dog, Cat and Man同じ例のクラスの実装を見てください。

于 2016-02-07T04:43:41.033 に答える