设计模式原则之接口隔离原则
接口隔离原则
1.什么是接口隔离原则
- Clients should not be forced to depend upon interfaces that they don't use.(客户端不应该强行依赖它不需要的接口)
- The dependency of one class to another one should depend on the smallest possible interface.(类间的依赖关系应该建立在最小的接口上)
通过简单的代码还原开篇的问题
需求如下
类A通过接口会依赖(使用)类C 但是类A只会使用到接口中的1,2,3方法
类B通过接口会依赖(使用)类D 但是类B只会使用到接口中的1,4,5方法
最初的接口中有五个方法
版本一
类A
public class ClassA { public void dependOnInterfaceOperationOne(InterfaceOriginal interfaceOriginal){ interfaceOriginal.operation1(); } public void dependOnInterfaceOperationTwo(InterfaceOriginal interfaceOriginal){ interfaceOriginal.operation2(); } public void dependOnInterfaceOperationThree(InterfaceOriginal interfaceOriginal){ interfaceOriginal.operation3(); } }
类B
public class ClassB { public void dependOnInterfaceOperationOne(InterfaceOriginal interfaceOriginal){ interfaceOriginal.operation1(); } public void dependOnInterfaceOperationFour(InterfaceOriginal interfaceOriginal){ interfaceOriginal.operation4(); } public void dependOnInterfaceOperationFive(InterfaceOriginal interfaceOriginal){ interfaceOriginal.operation5(); } }
类C
public class ClassC implements InterfaceOriginal { public void operation1(){ System.out.println("ClassC has implements operation1"); } public void operation2(){ System.out.println("ClassC has implements operation2"); } public void operation3(){ System.out.println("ClassC has implements operation3"); } public void operation4(){ System.out.println("ClassC has implements operation4"); } public void operation5(){ System.out.println("ClassC has implements operation5"); } }
类D
public class ClassD implements InterfaceOriginal{ public void operation1(){ System.out.println("ClassD has implements operation1"); } public void operation2(){ System.out.println("ClassD has implements operation2"); } public void operation3(){ System.out.println("ClassD has implements operation3"); } public void operation4(){ System.out.println("ClassD has implements operation4"); } public void operation5(){ System.out.println("ClassD has implements operation5"); } }
接口类
public interface InterfaceOriginal { void operation1(); void operation2(); void operation3(); void operation4(); void operation5(); }
Main函数类
public class ClassMain { public static void main(String[] args) { ClassA classA=new ClassA(); classA.dependOnInterfaceOperationOne(new ClassC()); classA.dependOnInterfaceOperationTwo(new ClassC()); classA.dependOnInterfaceOperationThree(new ClassC()); System.out.println("-------------"); ClassB classB=new ClassB(); classB.dependOnInterfaceOperationOne(new ClassD()); classB.dependOnInterfaceOperationFour(new ClassD()); classB.dependOnInterfaceOperationFive(new ClassD()); } }
控制台显示情况
UML类图
类A只用到了InterfaceOriginal接口中的OperationOne,OperationTwo,OperationThree.
类B只用到了InterfaceOriginal接口中的OperationOne,OperationFour,OperationFive
但是类A和类B同时依赖了不需要的接口 或者是说类间依赖的接口不是最小的 这就违反了接口隔离原则
从以上代码可以看出,如果接口过于臃肿,不同业务逻辑的抽象方法都放在一个接口内,则会造成它的实现类必须实现自己并不需要的方法,这种设计方式显然是不妥当的。所以我们要修改上述设计方法,把接口InterfaceOriginal拆分成3个接口,使得实现类只需要实现自己需要的接口即可。只贴出修改后的接口和实现类的代码,修改代码如下:
类A
public class ClassA { public void dependOnSegregationInterfaceOne(SegregationInterfaceOne interfaceOne){ interfaceOne.operationOne(); } public void dependOnSegregationInterfaceTwo(SegregationInterfaceTwo interfaceTwo){ interfaceTwo.operationTwo(); interfaceTwo.operationThree(); } }
类B
public class ClassB { public void dependOnSegregationInterfaceOne(SegregationInterfaceOne interfaceOne){ interfaceOne.operationOne(); } public void dependOnSegregationInterfaceThree(SegregationInterfaceThree interfaceThree){ interfaceThree.operationFour(); interfaceThree.operationFive(); } }
类C
public class ClassC implements SegregationInterfaceOne,SegregationInterfaceTwo{ public void operationOne(){ System.out.println("ClassC has implements operationOne"); } public void operationTwo(){ System.out.println("ClassC has implements operationTwo"); } public void operationThree(){ System.out.println("ClassC has implements operationThree"); } }
类D
public class ClassD implements SegregationInterfaceOne,SegregationInterfaceThree{ public void operationOne(){ System.out.println("ClassD has implements operationOne"); } public void operationFour(){ System.out.println("ClassD has implements operationFour"); } public void operationFive(){ System.out.println("ClassD has implements operationFive"); } }
隔离接口1
public interface SegregationInterfaceOne { void operationOne(); }
隔离接口2
public interface SegregationInterfaceTwo { void operationTwo(); void operationThree(); }
隔离接口3
public interface SegregationInterfaceThree { void operationFour(); void operationFive(); }
Main函数类
public class MainClass { public static void main(String[] args) { ClassA classA = new ClassA(); classA.dependOnSegregationInterfaceOne(new ClassC()); classA.dependOnSegregationInterfaceTwo(new ClassC()); System.out.println("----------------------"); ClassB classB = new ClassB(); classB.dependOnSegregationInterfaceOne(new ClassD()); classB.dependOnSegregationInterfaceThree(new ClassD()); } }
控制台运行结果
UML类图
这下类A和类B依赖的接口就是最小的 符合接口隔离原则
与单一职责原则的区别
到了这里,有些人可能觉得接口隔离原则与单一职责原则很相似,其实不然。
第一,单一职责原则注重的是职责;而接口隔离原则注重对接口依赖的隔离。
第二,单一职责原则主要是约束类,其次才是接口和方法,它针对的是程序中的实现和细节;而接口隔离原则主要约束接口,主要针对抽象,针对程序整体框架的构建。
注意事项
原则是前人经验的总结,在软件设计中具有一定的指导作用,但是不能完全照搬这些原则。对于接口隔离原则来说,接口尽量小,但是也要有限度。对接口进行细化可以提高程序设计灵活性是不争的事实,但是如果过小,则会造成接口数量过多,使设计复杂化,所以一定要适度。