连载:面向对象葵花宝典:思想、技巧与实践(33) - ISP原则
ISP,Interface Segregation Principle,中文翻译为“接口隔离原则”。
和DIP原则一样,ISP原则也是大名鼎鼎的Martin大师提出来的,他在1996年的C++ Reporter发表“ The Interface Segregation Principle”的文章具体阐述了ISP原则,并且在他的经典著作《 Agile Software Development, Principles, Patterns》(中文翻译为:敏捷软件开发:原则、模式与实践)、《Practices, and Agile Principles, Patterns, and Practices in C#》(中文翻译为:敏捷软件开发:原则、模式与实践(C#版))中详解了ISP原则。
ISP最原始的定义例如以下:
“CLIENTS SHOULD NOT BE FORCED TO DEPEND UPON INTERFACES THAT THEY DO NOT USE.”
翻译成中文就是“client不应该被强迫去依赖它们并不须要的接口”。
单纯从字面意思来看,ISP原则是5个原则中最好理解的一个了。可是我们深入思考一下,事实上发现也没有那么简单。假设你还记得我们前面讲的那些原则,你可能会想到一个问题:既然有了SRP,为什么还要ISP?
如今我们来回忆一下SRP原则,假设类满足了SRP原则,那么基于这个类提炼的接口不就自然而然的满足了ISP原则了么?为什么我们还要费神费力的又搞一个ISP原则呢?
Martin大师自然不会是吃饱了没事做,有益整个东东来折腾大家,他在ISP的论文中有这么一句话交代了ISP原则,可惜的是非常多人都没有把这句话贴出来:
|
The ISP acknowledges that there are objects that require non-cohesive interfaces; however it suggests that clients should not know about them as a single class. Instead, clients should know about abstract base classes that have cohesive interfaces. |
翻译一下:ISP原则承认对象须要非内聚的接口,然而ISP原则建议client不须要知道整个类,仅仅须要知道具有内聚接口的抽象父类就可以。
也就是说,ISP应用的场景是某些类不满足SRP原则,但使用这些类的client(即调用的类)应该依据接口来使用它,而不是直接使用它。
尽管翻译了一下,但还是比較抽象,给个样例一看就明确了,并且已经有一个非常好的样例了,即SRP原则中的“一体机”。
在“一体机”的样例中,尽管“一体机”同一时候具备“打印、复印、扫描、传真”的功能,但我们并不会设计一个“一体机”的接口,而是设计4个接口。这样调用接口的类能够依据自己须要精确使用某个接口,而不是调用一个大而全的接口。
具体代码例如以下:
ICopier.java
package com.oo.java.principles.isp; /**
* 复印机接口
*/
public interface ICopier { /**
* 复印
* @param paper
*/
void copy(Paper paper);
}
IFaxMachine.java
package com.oo.java.principles.isp; /**
* 传真机接口
*/
public interface IFaxMachine { /**
* 传真
* @param msg
*/
void fax(String msg);
}
IPrinter.java
package com.oo.java.principles.isp; /**
* 打印机接口
*/
public interface IPrinter { /**
* 打印
* @param doc
*/
void print(Document doc);
}
IScanner.java
package com.oo.java.principles.isp; /**
* 扫描仪接口
*/
public interface IScanner { /**
* 扫描
* @param paper
*/
void scan(Paper paper);
}
MultiFuncPrinter.java
package com.oo.java.principles.isp; /**
* 多功能打印机(一体机)
* 实现了IFaxMachine(传真机)、ICopier(复印机)、IPrinter(打印机)、IScanner(扫描仪)4个接口
* 而不是提供一个IMultiFuncPrinter的接口,同一时候提供以上接口的功能
*
*/
public class MultiFuncPrinter implements IFaxMachine, ICopier, IPrinter, IScanner { @Override
public void scan(Paper paper) {
// TODO Auto-generated method stub
} @Override
public void print(Document doc) {
// TODO Auto-generated method stub
} @Override
public void copy(Paper paper) {
// TODO Auto-generated method stub
} @Override
public void fax(String msg) {
// TODO Auto-generated method stub
}
}
People.java
package com.oo.java.principles.isp; /**
* 人
*/
public class People { /**
* 复印操作,copy方法依赖ICopier接口,而不是使用MutiFuncPrinter类
*/
public void copy(ICopier copier, Paper paper){
copier.copy(paper);
} /**
* 打印操作,print方法依赖IPrinter接口,而不是使用MutiFuncPrinter类
*/
public void print(IPrinter printer, Document doc){
printer.print(doc);
} /**
* 传真操作,fax方法依赖IFaxMachine接口,而不是使用MutiFuncPrinter类
*/
public void fax(IFaxMachine faxer, String message){
faxer.fax(message);
} /**
* 扫描操作,scan方法依赖IScanner接口,而不是使用MutiFuncPrinter类
*/
public void scan(IScanner scanner, Paper paper){
scanner.scan(paper);
}
}
Tester.java
package com.oo.java.principles.isp;
public class Tester {
public static void mai(String args[]){
People people = new People();
MultiFuncPrinter mfp = new MultiFuncPrinter();
//例如以下函数都是使用mfp作为參数,但实际上是使用了MultiFuncPrinter类实现了的不同接口
people.copy(mfp, new Paper()); //使用了MultiFuncPrinter类的ICopier接口,
people.fax(mfp, "I love oo"); //使用了MultiFuncPrinter类的IFaxMachine接口,
people.print(mfp, new Document()); //使用了MultiFuncPrinter类的IPrinter接口,
people.scan(mfp, new Paper()); //使用了MultiFuncPrinter类的IScanner接口,
}
}
连载:面向对象葵花宝典:思想、技巧与实践(33) - ISP原则的更多相关文章
- 连载:面向对象葵花宝典:思想、技巧与实践(28) - 设计原则:内聚&耦合
前面通过实例解说了一个一环扣一环的面向对象的开发流程:用例模型 -> 领域模型 -> 设计模型(类模型 + 动态模型),解答了面向对象怎样做的问题.接下来我们就要讲"怎样做好面向 ...
- IT第二十天 - 面向对象编程思想、抽象类、异常处理、程序操作日志记录、本周总结 ★★★
IT第二十天 上午 面向对象编程思想 1.组装电脑的设计: (1)电脑的组成:显示器+机箱 (2)机箱的组成:电源+主板+硬盘 (3)主板所包含的部件:cpu+内存+PCI接口+usb接口 (4)PC ...
- 黑马程序员——OC语言基础语法 面向对象的思想
Java培训.Android培训.iOS培训..Net培训.期待与您交流! (以下内容是对黑马苹果入学视频的个人知识点总结)(一)基础语法 1)关键字 @interface.@implementati ...
- Java面向对象的思想
面向对象的思想 1.面向对象的思想的特点: ①符合人们的日常思考习惯 ②能将复杂的问题简单化 ③将原来的执行者变为了现在的指挥者 面向对象的思想,所谓的对象,其实就是实体.对于实物的描述,通常有两个方 ...
- 面向对象编程思想(OOP)
本文我将从面向对象编程思想是如何解决软件开发中各种疑难问题的角度,来讲述我们面向对象编程思想的理解,梳理面向对象四大基本特性.七大设计原则和23种设计模式之间的关系. 软件开发中疑难问题: 软件复杂庞 ...
- U3D 飞机大战(MVC模式)解析--面向对象编程思想
在自己研究U3D游戏的时候,看过一些人的简单的游戏开发视频,写的不错,只是个人是java web 开发的人,所以结合着MVC思想,对游戏开发进行了一番考虑. 如果能把游戏更加的思想化,分工化,开发便明 ...
- OC - 1.面向过程和面向对象的思想对比
一.面向过程 1> 思想 面向过程是一种以过程为中心的最基础编程思想,不支持面向对象的特性. 面向过程是一种模块化程序设计方法 2> 开发方法 面向过程的开发方法是以过程(也可以说是模块) ...
- .net的自定义JS控件,运用了 面向对象的思想 封装 了 控件(.net自定义控件开发的第一天)
大家好!我叫刘晶,很高兴你能看到我分享的文章!希望能对你有帮助! 首先我们来看下几个例子 ,就能看到 如何 自定义控件! 业务需求: 制作 一个 属于 自己的 按钮 对象 ,然后 像 ...
- 面向对象编程思想(前传)--你必须知道的javascript
在写面向对象编程思想-设计模式中的js部分的时候发现很多基础知识不了解的话,是很难真正理解和读懂js面向对象的代码.为此,在这里先快速补上.然后继续我们的面向对象编程思想-设计模式. 什么是鸭子类型 ...
随机推荐
- Sublime text3配置LiveReload
Tip: LiveReload是很棒的插件,可以在浏览器中实时预览,但是在Sublime text3里,从Package Control中安装的LiveReload是无法使用的,但是可以选择手动安装解 ...
- xhtml规范
在使用XHTML语言进行网页制作时,必须要遵循一定的语法规范.下面进行详细讲解,其中具体内容可以分为以下几点. 文档方面: 必须定义文档类型(DTD)和你的名字空间 标签方面: 所有标签均要小写,合理 ...
- SuperSocket学习笔记(二)
上一篇博客SuperSocket学习笔记(一)说明了怎么快速搭建一个服务器端,这篇文章我想深挖一下SuperSocket 1. 每一个客户端连接到服务器端时,服务器端会将客户端的信息保存到一个Sess ...
- Jquery:Jquery中的DOM操作<二>
由于昨天晚上回来的晚,写的有点匆忙,所以昨天的学习笔记中出现了多处错误的地方,幸好有各位园友帮忙指出,在这里谢过各位了!今天继续学习关于Jquery中DOM的操作,其实是昨天随笔的延续,求围观!!! ...
- Struts2.3.16.3 基本9个jar包
实践证明,Struts2.3.16.3 至少要下面9个Jar包才能正常启动. commons-fileupload-1.3.1.jar commons-logging-1.1.3.jar freema ...
- jar打包命令
jar查看jar命令的使用 1. jar cvf 生成jar包的完整名称 要生成的class文件所在目录以及名称 jar -cvf aa.jar *.* 2.将jar包放到环境变量中,可以不用把cla ...
- Linux下的正则表达式(基础)
grep -n 'the' text.txt 搜寻含有the的部分(n代表现实显示行号) grep -vn 'the' text.txt 搜寻不含有the的部分(n代表现实显示行号) grep -vn ...
- Hdu1093
#include <stdio.h> int main() { int T,n; ; while(scanf("%d",&T)!=EOF){ while(sca ...
- Java笔记--File,FileInputStream,FileReader,InputStreamReader,BufferedReader 的使用和区别
转自:http://hi.baidu.com/danghj/item/0ef2e2c4ab95af7489ad9e39 参考资料: < core java > 12 章 使用 Java ...
- keepalived+httpd 做web服务的高可用
场景: 环境中有两台httpd服务器,一台做主,一台做备用:平时只用主向外提供http服务:当主宕机后,keepalived把vip绑定到备机上去,这样就由备机提供http服务了. **keepalv ...