接口隔离原则--对一个接口进行编程[英] Interface Segregation Principle- Program to an interface

本文是小编为大家收集整理的关于接口隔离原则--对一个接口进行编程的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

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

有区别吗?

推荐答案

ISP专注于代表一个离散和内聚行为的每个接口的想法.

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

其他推荐答案

罗伯特·马丁(Robert Martin)在他的书《 uml for java for java程序员》中对界面隔离原理(ISP)有很好的解释.基于此,我认为ISP并不是关于一个界面"专注"的界面,这是一个合乎逻辑的,连贯的事物.因为,不用说;或者,至少应该不用说.每个类,界面或抽象类都应以这种方式设计.

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

现在,

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

class B {
   A a = new A()
}

将成为

interface C {
  method1()
  method2()
}

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

class B {
  C c = new A()      
}   

这,阻止B比应该更多的了解.

其他推荐答案

假设您有一个具有许多可以实现的方法的脂肪接口.

任何类别都必须为所有这些方法提供实现的类别.其中一些方法可能不适用于该混凝土类.但是,在没有接口隔离​​原则的情况下,它仍然必须提供实施.

让我们看一下不存在接口隔离的示例代码.

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());

    }
}

输出:

java InterfaceNoSeggration
Rectangle area:200.0
Square area:225.0
Circle area:12.56

注意:

  1. Shape是一种通用脂肪接口,其中包含所有Shape实现所需的方法,例如Rectangle,Circle和Square.但是在各自形状的孩子中只需要一些方法

     Rectangle : getLength(), getWidth(), getArea()
     Square    : getLength() and getArea()
     Circle    : getRadius() and getArea()
    
  2. 在没有隔离的情况下,所有形状都实现了整个脂肪界面: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());

    }
}

注意:

现在,如Rectangle,Square和Circle之类的单个形状仅实现了所需的接口,并摆脱了未使用的方法.

本文地址:https://www.itbaoku.cn/post/627589.html

问题描述

I was reading about SOLID and other design principles. I thought ISP was the same as "Program to an interface, not an implementation". But it looks like these are different principles?

Is there a difference?

推荐答案

ISP is focused on the idea of each interface representing one discrete and cohesive behavior.

That is, each logical group of things an object should do would map to a single specific interface. A class might want to do several things, but each thing would map to a specific interface representing that behavior. The idea is each interface is very focused.

其他推荐答案

Robert Martin has a very good explanation of Interface segregation principle (ISP), in his book "UML for Java Programmers". Based on that, I don't think ISP is about an interface being "focused" on one logical, coherent group of things. Because, that goes without saying; or, at least it should go without saying. Each class, interface or abstract class should be designed that way.

So, what is ISP? Let me explain it with an example. Say, you have a class A and a class B, which is the client of class A. Suppose, class A has ten methods, of which only two are used by B. Now, does B need to know about all ten methods of A? Probably not - the principle of Information hiding. The more you expose, the more you create the chance for coupling. For that reason, you may insert an interface, call it C, between the two classes (segregation). That interface will only declare the two methods that are used by B, and B will depend on that Interface, instead of directly on A.

So now,

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

class B {
   A a = new A()
}

will become

interface C {
  method1()
  method2()
}

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

class B {
  C c = new A()      
}   

This, prevents B from knowing more than it should.

其他推荐答案

Assume that you have one fat interface with many methods to be implemented.

Any class, that implements that fat interface has to provide implementation for all these methods. Some of the methods may not be applicable to that concrete class. But still it has to provide implementation in absence of interface segregation principle.

Let's have a look at example code in absence of Interface segregation.

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());

    }
}

output:

java InterfaceNoSeggration
Rectangle area:200.0
Square area:225.0
Circle area:12.56

Notes:

  1. Shape is a general purpose fat interface, which contains methods required for all Shape implementations like Rectangle, Circle and Square. But only some methods are needed in respective Shape childs

     Rectangle : getLength(), getWidth(), getArea()
     Square    : getLength() and getArea()
     Circle    : getRadius() and getArea()
    
  2. In absence of segregation, all Shapes have implemented entire fat interface : Shape.

We can achieve same output with interface segregation principle if we change the code as follows.

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());

    }
}

Notes:

Now individual Shapes like Rectangle, Square and Circle have implemented only required interfaces and got rid of un-used methods.