Interface Segregation Principle


Six Principles of Design Patterns (4): Interface Isolation Principle (reproduced)

 

Definition: A client should not depend on interfaces it does not need; dependencies of one class on another should be built on the smallest interface.

The origin of the problem: class A depends on class B through interface I, and class C depends on class D through interface I. If interface I is not the smallest interface for class A and class B, then class B and class D must implement methods they do not need .

Solution: Split the bloated interface I into several independent interfaces, and class A and class C establish dependencies with the interfaces they need respectively. That is, the principle of interface isolation is adopted.

An example to illustrate the principle of interface isolation:

 

 

 

 

The meaning of this diagram is: class A depends on method 1, method 2, and method 3 in interface I, and class B is the implementation of class A dependency. Class C depends on method 1, method 4, and method 5 in interface I, and class D is the implementation of class C dependency. For class B and class D, although they both have unused methods (that is, the methods marked in red in the figure), because interface I is implemented, these unused methods must also be implemented. Those who are unfamiliar with class diagrams can refer to the program code to understand, the code is as follows:

 

interface I {  
    public void method1();  
    public void method2();  
    public void method3();  
    public void method4();  
    public void method5();  
}  
  
class A{  
    public void depend1(I i){  
        i.method1();  
    }  
    public void depend2(I i){  
        i.method2();  
    }  
    public void depend3(I i){  
        i.method3();  
    }  
}  
  
class B implements I{  
    public void method1() {  
        System.out.println("Class B implements method 1 of interface I");  
    }  
    public void method2() {  
        System.out.println("Class B implements method 2 of interface I");  
    }  
    public void method3() {  
        System.out.println("Class B implements method 3 of interface I");  
    }  
    //For class B, method4 and method5 are not necessary, but since there are these two methods in interface A,  
    //So in the implementation process, even if the method bodies of these two methods are empty, these two methods that have no effect should be implemented.  
    public void method4() {}  
    public void method5() {}  
}  
  
class C{  
    public void depend1(I i){  
        i.method1();  
    }  
    public void depend2(I i){  
        i.method4();  
    }  
    public void depend3(I i){  
        i.method5();  
    }  
}  
  
class D implements I{  
    public void method1() {  
        System.out.println("Class D implements method 1 of interface I");  
    }  
    //For class D, method2 and method3 are not necessary, but since there are these two methods in interface A,  
    //So in the implementation process, even if the method bodies of these two methods are empty, these two methods that have no effect should be implemented.  
    public void method2() {}  
    public void method3() {}  
  
    public void method4() {  
        System.out.println("Class D implements method 4 of interface I");  
    }  
    public void method5() {  
        System.out.println("Class D implements method 5 of interface I");  
    }  
}  
  
public class Client{  
    public static void main(String[] args){  
        A a = new A();  
        a.depend1(new B());  
        a.depend2(new B());  
        a.depend3(new B());  
          
        C c = new C();  
        c.depend1(new D());  
        c.depend2(new D());  
        c.depend3(new D());  
    }  
}  

It can be seen that if the interface is too bloated, as long as the methods appearing in the interface are useful to the classes that depend on it, the implementing class must implement these methods, which is obviously not a good design. If this design is modified to conform to the interface segregation principle, interface I must be split. Here we split the original interface I into three interfaces, and the split design is shown in Figure 2:

 

 

 

As usual, the code of the program is posted for the reference of friends who are not familiar with class diagrams:

 

interface I1 {  
    public void method1();  
}  
  
interface I2 {  
    public void method2();  
    public void method3();  
}  
  
interface I3 {  
    public void method4();  
    public void method5();  
}  
  
class A{  
    public void depend1(I1 i){  
        i.method1();  
    }  
    public void depend2(I2 i){  
        i.method2();  
    }  
    public void depend3(I2 i){  
        i.method3();  
    }  
}  
  
class B implements I1, I2{  
    public void method1() {  
        System.out.println("Class B implements method 1 of interface I1");  
    }  
    public void method2() {  
        System.out.println("Class B implements method 2 of interface I2");  
    }  
    public void method3() {  
        System.out.println("Class B implements method 3 of interface I2");  
    }  
}  
  
class C{  
    public void depend1(I1 i){  
        i.method1();  
    }  
    public void depend2(I3 i){  
        i.method4();  
    }  
    public void depend3(I3 i){  
        i.method5();  
    }  
}  
  
class D implements I1, I3{  
    public void method1() {  
        System.out.println("Class D implements method 1 of interface I1");  
    }  
    public void method4() {  
        System.out.println("Class D implements method 4 of interface I3");  
    }  
    public void method5() {  
        System.out.println("Class D implements method 5 of interface I3");  
    }  
}

   The meaning of the interface isolation principle is: build a single interface, do not build a huge and bloated interface, try to refine the interface, and minimize the methods in the interface. That is to say, we have to create dedicated interfaces for each class, instead of trying to create a huge interface for all classes that depend on it to call. In this example, the interface isolation principle is used to change a huge interface into three dedicated interfaces. In programming, it is more flexible to rely on several specialized interfaces than to rely on one comprehensive interface. An interface is a "contract" set to the outside during design. By defining multiple interfaces in a decentralized manner, the proliferation of external changes can be prevented, and the flexibility and maintainability of the system can be improved.

         Having said that, many people think that the interface isolation principle is very similar to the previous single responsibility principle, but it is not. First, the single responsibility principle originally focused on responsibility; the interface isolation principle focused on the isolation of interface dependencies. Second, the principle of single responsibility is mainly to constrain classes, followed by interfaces and methods, which are aimed at the implementation and details in the program; while the principle of interface isolation mainly constrains the interface interface, mainly for abstraction, for the construction of the overall framework of the program.

 

When using the interface isolation principle to constrain interfaces, pay attention to the following points:

  • The interface should be as small as possible, but there should be limits. It is a fact that refining the interface can improve the flexibility of programming, but if it is too small, it will cause too many interfaces and complicate the design. So be in moderation.
  • Customize services for classes that depend on the interface, only expose the methods it needs to the calling class, and hide the methods it doesn't need. Minimal dependencies can only be established by focusing on providing custom services for one module.
  • Improve cohesion and reduce external interaction. Make the interface do the most things with the fewest methods.

The principle of interface isolation must be used in moderation. It is not good to design an interface that is too large or too small. When designing an interface, you can only practice this principle accurately if you spend more time thinking and planning.

 

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326692661&siteId=291194637