接口隔离原理 - 编程到接口

han*_*r18 21 oop design-patterns solid-principles interface-segregation-principle

我正在阅读有关SOLID和其他设计原则的内容.我认为ISP与"程序接口,而非实现"相同.但看起来这些是不同的原则?

有区别吗?

Naz*_*rza 39

Robert Martin在他的"UML for Java Programmers"一书中对接口隔离原则(ISP)有很好的解释.基于此,我不认为ISP是关于一个界面"聚焦"在一个逻辑,连贯的事物上的界面.因为,这是不言而喻的; 或者,至少应该不言而喻.应该以这种方式设计每个类,接口或抽象类.

那么,什么是ISP?让我用一个例子解释一下.比如,你有一个A类和一个B类,它是A类的客户端.假设,A类有十个方法,其中只有两个被B使用.现在,B需要知道A的所有十种方法?可能不是 - 信息隐藏的原则.你暴露的越多,你创造耦合的机会就越多.因此,您可以在两个类之间插入一个接口,称之为C(隔离).该接口只会声明B使用的两种方法,而B将依赖于该接口,而不是直接依赖于A.

所以现在,

class A {
  method1()
  method2()
  // more methods
  method10()
}

class B {
   A a = new A()
}
Run Code Online (Sandbox Code Playgroud)

会变成

interface C {
  method1()
  method2()
}

class A implements C{
  method1()
  method2()
  // more methods
  method10()
}

class B {
  C c = new A()      
}   
Run Code Online (Sandbox Code Playgroud)

这样可以防止B知道更多.

  • 我认为@Pete Stensønes 的解释比我所做的更笼统和准确。我建议人们多关注他的定义。我的,虽然不一定是错误的,但根据它的一个用例来解释这个概念,而忽略了它的一般观点。 (2认同)
  • 我不完全理解这种说法,即应该阻止客户了解其他方法。使用Java,当它不使用这些方法时,显然不会对那些未使用的方法发生变化产生任何影响。 (2认同)

Pet*_*nes 32

ISP专注于每个界面代表一种离散和凝聚行为的想法.

也就是说,对象应该做的每个逻辑组都将映射到单个特定接口.类可能想要做几件事,但每件事都会映射到表示该行为的特定接口.这个想法是每个界面都非常集中.

  • +1.经典的"气味"告诉你你没有遵循这个原则是一个客户端消费(取决于)一个接口,客户端只调用接口方法的一个子集. (4认同)

Rav*_*abu 10

假设您有一个胖接口,其中包含许多要实现的方法.

任何实现该胖接口的类都必须为所有这些方法提供实现.某些方法可能不适用于该具体类.但是在没有接口隔离​​原则的情况下仍然必须提供实现.

让我们看看没有接口隔离​​的示例代码.

interface Shape{
    public int getLength();
    public int getWidth();
    public int getRadius();
    public double getArea();
}

class Rectangle implements Shape{
    int length;
    int width;
    public Rectangle(int length, int width){
        this.length = length;
        this.width = width;
    }
    public int getLength(){
        return length;
    }
    public int getWidth(){
        return width;
    }
    public int getRadius(){
        // Not applicable
        return 0;
    }
    public double getArea(){
        return width * length;
    }
}
class Square implements Shape{
    int length;

    public Square(int length){
        this.length = length;
    }
    public int getLength(){
        return length;
    }
    public int getWidth(){
        // Not applicable
        return 0;
    }
    public int getRadius(){
        // Not applicable
        return 0;
    }
    public double getArea(){
        return length * length;
    }
}

class Circle implements Shape{
    int radius;
    public Circle(int radius){
        this.radius = radius;
    }
    public int getLength(){
        // Not applicable
        return 0;
    }
    public int getWidth(){
        // Not applicable
        return 0;
    }
    public int getRadius(){
        return radius;
    }
    public double getArea(){
        return 3.14* radius * radius;
    }
}

public class InterfaceNoSeggration{
    public static void main(String args[]){
        Rectangle r = new Rectangle(10,20);
        Square s = new Square(15);
        Circle c = new Circle(2);
        System.out.println("Rectangle area:"+r.getArea());
        System.out.println("Square area:"+s.getArea());
        System.out.println("Circle area:"+c.getArea());

    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

java InterfaceNoSeggration
Rectangle area:200.0
Square area:225.0
Circle area:12.56
Run Code Online (Sandbox Code Playgroud)

笔记:

  1. Shape是一个通用的脂肪接口,它包含所有所需的方法Shape等的实现Rectangle,CircleSquare.但是在各个Shape子项中只需要一些方法

     Rectangle : getLength(), getWidth(), getArea()
     Square    : getLength() and getArea()
     Circle    : getRadius() and getArea()
    
    Run Code Online (Sandbox Code Playgroud)
  2. 在没有隔离的情况下,所有Shapes都实现了整个胖接口:Shape.

如果我们改变代码如下,我们可以用接口隔离原理实现相同的输出.

interface Length{
    public int getLength();
}
interface Width{
    public int getWidth();
}
interface Radius{
    public int getRadius();
}
interface Area {
    public double getArea();
}


class Rectangle implements Length,Width,Area{
    int length;
    int width;
    public Rectangle(int length, int width){
        this.length = length;
        this.width = width;
    }
    public int getLength(){
        return length;
    }
    public int getWidth(){
        return width;
    }
    public int getRadius(){
        // Not applicable
        return 0;
    }
    public double getArea(){
        return width * length;
    }
}
class Square implements Length,Area{
    int length;

    public Square(int length){
        this.length = length;
    }
    public int getLength(){
        return length;
    }
    public int getWidth(){
        // Not applicable
        return 0;
    }
    public int getRadius(){
        // Not applicable
        return 0;
    }
    public double getArea(){
        return length * length;
    }
}

class Circle implements Radius,Area{
    int radius;
    public Circle(int radius){
        this.radius = radius;
    }
    public int getLength(){
        // Not applicable
        return 0;
    }
    public int getWidth(){
        // Not applicable
        return 0;
    }
    public int getRadius(){
        return radius;
    }
    public double getArea(){
        return 3.14* radius * radius;
    }
}

public class InterfaceSeggration{
    public static void main(String args[]){
        Rectangle r = new Rectangle(10,20);
        Square s = new Square(15);
        Circle c = new Circle(2);
        System.out.println("Rectangle area:"+r.getArea());
        System.out.println("Square area:"+s.getArea());
        System.out.println("Circle area:"+c.getArea());

    }
}
Run Code Online (Sandbox Code Playgroud)

笔记:

现在个别Shapes就像Rectangle,Square并且Circle只实现了所需的接口并摆脱了未使用的方法.