27

接口隔离原则只是单一职责原则的替代品吗?

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

所以 ISP 看起来像是解决方案,以防我们出于某种原因不得不破坏 SRP。

我对吗 ?

4

3 回答 3

33

不。以一个负责将数据持久保存在例如硬盘上的类为例。将课程分成读和写部分没有实际意义。但是有些客户端应该只使用该类来读取数据,有些客户端只用于写入数据,有些则两者兼而有之。在这里应用具有三个不同接口的 ISP 将是一个不错的解决方案。

于 2011-11-11T19:42:15.910 回答
19

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

单一职责原则是一个类(或一个方法)不应该有多个改变的理由(即每个只负责一个特性)。为了兑现这一点,您会发现自己随着系统的发展而创建了新的类。

例如,如果你从一个Car类开始并发现你需要改变齿轮的功能,你将把它提取到一个Gearbox类中。这意味着如果您更改齿轮更改背后的机制,则父Car类不需要更改。如果您为您的汽车添加动力转向,您将再次将其提取到它自己的类中。收音机将是另一门课。

这种抽象的级联将在您的整个Car班级中发生。当您从Car自身向下移动时,您会发现每个类的细节都在增加——例如,虽然Car该类可能有一个changeGear()方法允许用户选择要使用的齿轮,但Gearbox该类将关注制作的细节发生这种情况(例如踩下离合器、分离当前档位、选择新档位等)

然而,对于 OO 设计,我们不希望将我们的细节暴露Gearbox给最终用户——我们希望他们与我们的系统进行高度抽象的交互,而不需要知道内部是如何工作的。我们还希望隔离这些内部结构,以便我们可以在将来更改它们而无需用户重构他们的代码(这就是我们将它们标记为privateor的原因protected)。

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

于 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 回答