接口隔离原则是否只能替代单一责任原则?

时间:2011-11-11 19:35:45

标签: design-patterns solid-principles single-responsibility-principle interface-segregation-principle

界面隔离原则是否只是单一责任原则的替代?

我认为如果我的班级满足SRP,则无需提取多个界面。

所以ISP看起来像解决方案,以防我们因某种原因打破SRP。

我是对的吗?

3 个答案:

答案 0 :(得分:29)

没有。以一个类为例,该类的职责是持久保存数据。硬盘。将类拆分为读写部分并不具有实际意义。但是有些客户端应该只使用类来读取数据,有些客户端只能用来写数据,有些客户端只能用来读取数据。在这里使用三个不同的接口应用ISP将是一个很好的解决方案。

答案 1 :(得分:18)

  

我认为如果我的班级满足SRP,则无需提取更多内容   比一个界面。

单一责任原则是一个类(或方法)不应该有多个改变的原因(即每个只负责一个功能)。为了兑现这一点,您将发现自己在系统开发时创建新类。

E.g。如果你开始使用Car课程&发现你需要改变齿轮的功能,你将把它提取到一个Gearbox类。这意味着如果更改齿轮更改后面的机制,则不需要更改父Car类。如果你为你的汽车添加动力转向,你将再次将它提取到它自己的班级。收音机将是另一个班级。

这个抽象级联将在您的Car课程中发生。当您从Car本身向下移动时,您会发现每个班级的细节都会增加 - 例如虽然Car类可能有一个changeGear()方法允许用户选择要参与的工具,但Gearbox类将会考虑实现这一点的细节(例如,压低离合器,脱离当前档位,选择新档位等。)

但是,通过OO设计,我们不希望将Gearbox的详细信息公开给最终用户 - 我们希望它们以高抽象级别与我们的系统交互,而无需知道如何内部工作。我们还希望对这些内部进行封锁,以便我们可以在将来更改它们而无需用户重构其代码(这就是为什么我们将它们标记为privateprotected)。

因此,我们只允许用户通过Car类本身与我们的汽车互动。 这个接口隔离原则的用武之地.SRP确保Car类将其子组件委托给不同的类,但是我们所有的{{1}仍将通过public类本身调用方法。 ISP 确保不是将所有这些集中在一个界面中,而是创建逻辑区别&为相关功能公开多个接口。

答案 2 :(得分: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类的实现。