1. Basic introduction
Clients should not rely on interfaces they do not need, that is, a class's dependence on another class should be based on the smallest interface
It can be seen from the figure that:
1. Class a relies on class B through interface interface 1, but only uses methods 1, 2, 3
2. Class C relies on class D through interface interface 1, but only uses methods 1, 4, 5
3. Class a depends on class B through interface Interface1, and class C depends on class D through interface Interface1
4. If interface interface 1 is not the minimum interface for class A and class C, class B and class D must implement methods they do not need
According to the principle of interface isolation:
The interface interface 1 is divided into several independent interfaces. Class A and class C respectively establish the dependency relationship with the interfaces they need
2. Application cases
-
Code isolated without interface
public class Segregation1 { public static void main(String[] args) { } } //Interface interface Interface1 { void operation1(); void operation2(); void operation3(); void operation4(); void operation5(); } class B implements Interface1 { public void operation1() { System.out.println("B operation1"); } public void operation2() { System.out.println("B operation2"); } public void operation3() { System.out.println("B operation3"); } public void operation4() { System.out.println("B operation4"); } public void operation5() { System.out.println("B operation5"); } } class D implements Interface1 { public void operation1() { System.out.println("D operation1"); } public void operation2() { System.out.println("D operation2"); } public void operation3() { System.out.println("D operation3"); } public void operation4() { System.out.println("D operation4"); } public void operation5() { System.out.println("D operation5"); } } class A { //Class A relies on class B through interface interface 1, but only uses methods 1, 2, 3 public void depend1(Interface1 i) { i.operation1(); } public void depend2(Interface1 i) { i.operation2(); } public void depend3(Interface1 i) { i.operation3(); } } class C { //Class C relies on class D through interface interface 1, but only uses methods 1, 4, 5 public void depend1(Interface1 i) { i.operation1(); } public void depend4(Interface1 i) { i.operation4(); } public void depend5(Interface1 i) { i.operation5(); } }
Since the principle of interface isolation is not adopted, although class A only needs to use methods 1, 2 and 3 in Interface1 through class B, it has to implement methods 4 and 5 in Interface1: Class C only needs methods 1, 4 and 5 in Interface1 through class D, but has to implement methods 2 and 3 in the interface, which will cause too much redundant code and appear overstaffed
resolvent:
It divides Interface1 into three interfaces: Interface1(operation1), Interface2(operation2,operation3), Interface3(operation4,operation5) to implement their own interfaces according to their requirements -
Code isolated with interface
public class Segregation1 { public static void main(String[] args) { A a = new A(); a.depend1(new B()); // Class A depends on class B through interface a.depend2(new B()); a.depend3(new B()); C c = new C(); c.depend1(new D()); // Class C depends on class D through interface c.depend4(new D()); c.depend5(new D()); } } // Interface 1 interface Interface1 { void operation1(); } // Interface 2 interface Interface2 { void operation2(); void operation3(); } // Interface 3 interface Interface3 { void operation4(); void operation5(); } class B implements Interface1, Interface2 { public void operation1() { System.out.println("B operation1"); } public void operation2() { System.out.println("B operation2"); } public void operation3() { System.out.println("B operation3"); } } class D implements Interface1, Interface3 { public void operation1() { System.out.println("D operation1"); } public void operation4() { System.out.println("D operation4"); } public void operation5() { System.out.println("D operation5"); } } class A { // Class A relies on class B through interface 1, and interface 2 only uses methods 1, 2, and 3 public void depend1(Interface1 i) { i.operation1(); } public void depend2(Interface2 i) { i.operation2(); } public void depend3(Interface2 i) { i.operation3(); } } class C { // Class C depends on (uses) class D through Interface1,Interface3, but only uses methods 1,4,5 public void depend1(Interface1 i) { i.operation1(); } public void depend4(Interface3 i) { i.operation4(); } public void depend5(Interface3 i) { i.operation5(); } }
3. Precautions and details
- Clients should not rely on interfaces they do not need
- Dependencies between classes should be based on minimal interfaces
- Don't put a lot of methods in an interface, which will make the class look bloated. The interface should be as detailed as possible, one interface corresponds to one functional module, and at the same time, the methods in the interface should be as few as possible to make the interface more portable and flexible
- The principle of single responsibility requires a single class and interface responsibility, focusing on the division of business logic, while the principle of interface isolation requires as few methods as possible, which is considered in interface design. For example, the responsibility of an interface includes 10 methods, all of which are placed in one interface and provided to multiple modules for access. Each module accesses according to the specified permissions and stipulates that "the unused methods cannot be accessed". Such a design does not conform to the interface isolation principle, which requires "as many specialized interfaces as possible", which is specialized here The interface provided to each module should be a single interface (that is, each module corresponds to an interface), rather than a huge and bloated interface to accommodate all client access