1.基本介绍
客户端不应该依赖它不需要的接口,即一个类对另一个类的依赖应该建立在最小的接口上
由图可知:
1.A类通过接口Interface1依赖(使用) B类,但是只会用到1,2,3方法
2.C类通过接口Interface1依赖(使用) D类,但是只会用到1,4,5方法
3.A类通过接口Interface1依赖类B,类C通过接口Interface1依赖D
4.如果接口Interface1对于类A和类C来说都不是最小接口,那么类B和类D必须去实现他们不需要的方法
按照接口隔离原则:
将接口Interface1拆分为独立的几个接口,类A和类C分别与他们需要的接口建立依赖关系
2.应用案例
-
未使用接口隔离的代码
public class Segregation1 { public static void main(String[] args) { } } //接口 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 { //A 类通过接口Interface1 依赖(使用) B类,但是只会用到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 { //C 类通过接口Interface1 依赖(使用) D类,但是只会用到1,4,5方法 public void depend1(Interface1 i) { i.operation1(); } public void depend4(Interface1 i) { i.operation4(); } public void depend5(Interface1 i) { i.operation5(); } }
由于未采用接口隔离原则,虽然A类通过B类只需要使用Interface1中的1,2,3方法,但是不得不实现Interface1中的4,5方法:C类通过D类只需要使用Interface1的1,4,5方法但是不得不实现接口的2,3方法,这样会造成过多的冗余代码,显得类臃肿不堪
解决方法:
将Interface1 拆分为3个接口:Interface1(operation1),Interface2(operation2,operation3),Interface3(operation4,operation5)根据各自的需求实现各自的接口 -
使用接口隔离的代码
public class Segregation1 { public static void main(String[] args) { A a = new A(); a.depend1(new B()); // A类通过接口去依赖B类 a.depend2(new B()); a.depend3(new B()); C c = new C(); c.depend1(new D()); // C类通过接口去依赖(使用)D类 c.depend4(new D()); c.depend5(new D()); } } // 接口1 interface Interface1 { void operation1(); } // 接口2 interface Interface2 { void operation2(); void operation3(); } // 接口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 { // A 类通过接口Interface1,Interface2 依赖(使用) B类,但是只会用到1,2,3方法 public void depend1(Interface1 i) { i.operation1(); } public void depend2(Interface2 i) { i.operation2(); } public void depend3(Interface2 i) { i.operation3(); } } class C { // C 类通过接口Interface1,Interface3 依赖(使用) D类,但是只会用到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.注意事项和细节
- 客户端不应该依赖它不需要的接口
- 类间的依赖关系应该建立在最小的接口上
- 不要在一个接口里面放很多的方法,这样会显得这个类很臃肿不堪。接口应该尽量细化,一个接口对应一个功能模块,同时接口里面的方法应该尽可能的少,使接口更加轻便灵活
- 单一职责原则要求类和接口职责单一,注重的是职责,是业务逻辑上的划分,而接口隔离原则要求方法要尽可能的少,是在接口设计上的考虑。例如一个接口的职责包含10个方法,这10个方法都放在一个接口中,并且提供给多个模块访问,各个模块按照规定的权限来访问,并规定了“不使用的方法不能访问”,这样的设计是不符合接口隔离原则的,接口隔离原则要求“尽量使用多个专门的接口”,这里专门的接口就是指提供给每个模块的都应该是单一接口(即每一个模块对应一个接口),而不是建立一个庞大臃肿的接口来容纳所有的客户端访问