设计模式六大原则(4):接口隔离原则(Interface Segregation Principle)
2015-12-23 10:57
323 查看
接口隔离原则:
使用多个专门的接口比使用单一的总接口要好。
一个类对另外一个类的依赖性应当是建立在最小的接口上的。
一个接口代表一个角色,不应当将不同的角色都交给一个接口。没有关系的接口合并在一起,形成一个臃肿的大接口。这是对角色和接口的污染。
“不应该强迫客户依赖于它们不用的方法。
接口属于客户。不属于它所在的类层次结构。”这个说得非常明确了。再通俗点说,不要强迫客户使用它们不用的方法,假设强迫用户使用它们不使用的方法。那么这些客户就会面临因为这些不使用的方法的改变所带来的改变。
定义:client不应该依赖它不须要的接口;一个类对还有一个类的依赖应该建立在最小的接口上。
问题由来:类A通过接口I依赖类B,类C通过接口I依赖类D。假设接口I对于类A和类B来说不是最小接口,则类B和类D必须去实现他们不须要的方法。
解决方式:将臃肿的接口I拆分为独立的几个接口,类A和类C分别与他们须要的接口建立依赖关系。也就是採用接口隔离原则。
举例来说明接口隔离原则:
(图1 未遵循接口隔离原则的设计)
这个图的意思是:类A依赖接口I中的方法1、方法2、方法3,类B是对类A依赖的实现。
类C依赖接口I中的方法1、方法4、方法5,类D是对类C依赖的实现。对于类B和类D来说,尽管他们都存在着用不到的方法(也就是图中红色字体标记的方法)。但因为实现了接口I,所以也必需要实现这些用不到的方法。对类图不熟悉的能够參照程序代码来理解,代码例如以下:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778 | 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("类B实现接口I的方法1"); } public void method2() { System.out.println("类B实现接口I的方法2"); } public void method3() { System.out.println("类B实现接口I的方法3"); } //对于类B来说,method4和method5没必要的,可是因为接口A中有这两个方法。 //所以在实现过程中即使这两个方法的方法体为空,也要将这两个没有作用的方法进行实现。 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("类D实现接口I的方法1"); } //对于类D来说,method2和method3没必要的,可是因为接口A中有这两个方法, //所以在实现过程中即使这两个方法的方法体为空,也要将这两个没有作用的方法进行实现。 public void method2() {} public void method3() {} public void method4() { System.out.println("类D实现接口I的方法4"); } public void method5() { System.out.println("类D实现接口I的方法5"); }} 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()); }} |
(图2 遵循接口隔离原则的设计)
照例贴出程序的代码。供不熟悉类图的朋友參考:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | interfaceI1{ publicvoidmethod1(); } interfaceI2{ publicvoidmethod2(); publicvoidmethod3(); } interfaceI3{ publicvoidmethod4(); publicvoidmethod5(); } classA{ publicvoiddepend1(I1i){ i.method1(); } publicvoiddepend2(I2i){ i.method2(); } publicvoiddepend3(I2i){ i.method3(); } } classBimplementsI1,I2{ publicvoidmethod1(){ System.out.println("类B实现接口I1的方法1"); } publicvoidmethod2(){ System.out.println("类B实现接口I2的方法2"); } publicvoidmethod3(){ System.out.println("类B实现接口I2的方法3"); } } classC{ publicvoiddepend1(I1i){ i.method1(); } publicvoiddepend2(I3i){ i.method4(); } publicvoiddepend3(I3i){ i.method5(); } } classDimplementsI1,I3{ publicvoidmethod1(){ System.out.println("类D实现接口I1的方法1"); } publicvoidmethod4(){ System.out.println("类D实现接口I3的方法4"); } publicvoidmethod5(){ System.out.println("类D实现接口I3的方法5"); } } |
接口是设计时对外部设定的“契约”,通过分散定义多个接口。能够预防外来变更的扩散,提高系统的灵活性和可维护性。
讲到这里。非常多人会觉的接口隔离原则跟之前的单一职责原则非常相似。事实上不然。其一,单一职责原则原注重的是职责。而接口隔离原则注重对接口依赖的隔离。
其二。单一职责原则主要是约束类,其次才是接口和方法。它针对的是程序中的实现和细节。而接口隔离原则主要约束接口接口,主要针对抽象,针对程序总体框架的构建。
採用接口隔离原则对接口进行约束时。要注意下面几点:
接口尽量小,可是要有限度。
对接口进行细化能够提高程序设计灵活性是不挣的事实,可是假设过小。则会造成接口数量过多。使设计复杂化。所以一定要适度。
为依赖接口的类定制服务。仅仅暴露给调用的类它须要的方法,它不须要的方法则隐藏起来。
仅仅有专注地为一个模块提供定制服务,才干建立最小的依赖关系。
提高内聚。降低对外交互。使接口用最少的方法去完毕最多的事情。
运用接口隔离原则,一定要适度,接口设计的过大或过小都不好。设计接口的时候。仅仅有多花些时间去思考和筹划,才干准确地实践这一原则。
相关文章推荐
- snmp trap编写
- Centos7安装完毕后无法联网的解决方法
- TOMCAT应用部署
- Android Bundle类
- Python 的Logging模块
- linux进程间的通信: 信号量
- Brainteaser:Bulb Switcher
- I/O复用套接字编程
- VB学习之问与答
- PHP、JAVA、C#、Object-C、Android 通用的DES加密解密
- 快速熟悉shell
- GitBook 配置说明
- 线程阻塞
- jQuery实现无限加载瀑布流特效
- centos批量修改文件名
- 编辑器中换行
- python之反射
- 1093: [ZJOI2007]最大半连通子图
- Ios 生成 Ipa 的命令行
- Swift中的集合类型