4.接口隔离原则(Interface Segregation Principle)
1.定义
客户端不应该依赖它不需要的接口;
一个类对另一个类的依赖应该建立在最小的接口上。
2.定义解读
定义包含三层含义:
- 一个类对另一个类的依赖应该建立在最小的接口上;
- 一个接口代表一个角色,不应该将不同的角色都交给一个接口,因为这样可能会形成一个臃肿的大接口;
- 不应该强迫客户依赖它们从来不用的方法。
接口隔离原则有点像单一职责原则,但是也有区别,在单一职责原则中,一个接口可能有多个方法,提供给多种不同的调用者所调用,但是它们始终完成同一种功能,因此它们符合单一职责原则,却不符合接口隔离原则,因为这个接口存在着多种角色,因此可以拆分成更多的子接口,以供不同的调用者所调用。比如说,项目中我们通常有一个Web服务管理的类,接口定义中,我们可能会将所有模块的数据调用方法都在接口中进行定义,因为它们都完成的是同一种功能:和服务器进行数据交互;但是对于具体的业务功能模块来说,其他模块的数据调用方法它们从来不会使用,因此不符合接口隔离原则。
3.优点
使用接口隔离原则,意在设计一个短而小的接口和类,符合我们常说的高内聚低耦合的设计思想,从而使得类具有很好的可读性、可扩展性和可维护性。
4.问题提出
类A通过接口I依赖类B,类C通过接口I依赖类D,如果接口I对于类A和类C来说不是最小接口,而类B和类D必须去实现它们不需要的方法。下面通过一个UML图来说明这种现象:

在这里,我们定义了一个动物活动的接口IAnimal,里面有4个方法:飞行fly、行走walk、吃eat和工作work,然后分别用人类People和鸟类Bird实现了这个接口。中国人类ChinesePeople和鹦鹉类Parrot通过接口IAnimal分别依赖类People和类Bird。很明显,对于ChinesePeople来说,fly方法是多余的,因为人不会飞;对于Parrot类来说,work方法是多余的,因为鹦鹉不需要工作。接口IAnimal对于类ChinesePeople和类Parrot来说不是最小接口。
5.解决方案
将臃肿的接口IAnimal拆分为独立的几个接口,类ChinesePeople和类Parrot分别与它们需要的接口建立依赖关系,也就是采用接口隔离原则。修改后的UML图如下所示:

6.示例
import Foundation @objc protocol IAnimal
{
optional func walk();
func eat();
} protocol IPeople
{
func work();
} protocol IBird
{
func fly();
} class People: NSObject, IAnimal, IPeople
{
func walk()
{
print("People walk");
} func eat()
{
print("People eat");
} func work()
{
print("People work");
}
} class Bird: NSObject, IAnimal, IBird
{
func eat()
{
print("Bird eat");
} func fly()
{
print("Bird Fly");
}
} class ChinesePeople
{
var chinesePeople: protocol<IAnimal, IPeople>?; func peopleWalk()
{
chinesePeople?.walk!();
} func peopleEat()
{
chinesePeople?.eat();
} func peopleWork()
{
chinesePeople?.work();
}
} class Parrot
{
var parrot: protocol<IAnimal, IBird>?; func parrotEat()
{
parrot?.eat();
} func parrotFly()
{
parrot?.fly();
}
} let chinesePeople = ChinesePeople();
chinesePeople.chinesePeople = People();
chinesePeople.peopleEat(); //打印:People eat let parrot = Parrot();
parrot.parrot = Bird();
parrot.parrotEat(); //打印:Bird eat
说明:从UML图可以看到,遵守接口隔离原则,会使代码量增加不少,源码中也是这样;实际上,IOS在定义协议的时候,可以设置方法为可选实现(optional)和必须实现(默认值),我们可以设置work方法和fly方法为可选实现的方法,这样在类People和类Bird中,这两个方法可以根据需要来决定是否实现。采用这种方式,功能上实现是没有问题,对于简单的接口来说,也便于维护和管理。但是,当方法随着业务需求的增加而不断增加的话,如果我们不应用接口隔离原则,那么就可能形成一个庞大臃肿的接口,这样的接口的可维护性和重用性是很差的。因此,我们应该尽量细化接口,本篇将一个接口变更为3个专用的接口所采用的就是接口隔离原则。在项目开发中,依赖几个专用的接口要比依赖一个综合的接口更加灵活。通过分散定义多个接口,可以预防外来变更的扩散,提高系统的灵活性和可维护性。
虽然接口隔离原则很有意义,但在实际项目中,应该注意度的把握,接口设计的过大或过小都不好,应该根据实际情况多思考再进行设计。
4.接口隔离原则(Interface Segregation Principle)的更多相关文章
- 设计模式六大原则(四):接口隔离原则(Interface Segregation Principle)
接口隔离原则(ISP)定义: 客户端不应该依赖它不需要的接口:一个类对另一个类的依赖应该建立在最小的接口上. 问题由来: 类A通过接口I依赖类B,类C通过接口I依赖类D,如果接口I对于类A和类B来说不 ...
- 接口隔离原则(Interface Segregation Principle, ISP)
使用多个专门的接口,而不使用单一的总接口 接口隔离有两种定义: Clients should not be forced to depend upon interfaces that they don ...
- 面象对象设计原则之四:接口隔离原则(The Interface Segregation Principle,ISP)
接口隔离原则定义如下: 接口隔离原则(Interface Segregation Principle, ISP):使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口. 根 ...
- 设计模式之六大原则——接口隔离原则(ISP)
设计模式之六大原则——接口隔离原则(ISP) 转载于:http://www.cnblogs.com/muzongyan/archive/2010/08/04/1792528.html 接口隔离原则 ...
- 设计模式值六大原则——接口隔离原则 (ISP)
接口隔离原则 Interface Segregation Principle 定义: 客户端不应该依赖它不需要的接口 类间的依赖关系应该建立在最小的接口上 我们可以把这两个定义概括为一句话:建立 ...
- 【面向对象设计原则】之接口隔离原则(ISP)
接口隔离原则(Interface Segregation Principle, ISP):使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口. 从接口隔离原则的定义可以看 ...
- Java设计原则—接口隔离原则(转)
接口隔离原则 Interface Segregation Principle 定义: 客户端不应该依赖它不需要的接口 类间的依赖关系应该建立在最小的接口上 我们可以把这两个定义概括为一句话:建立 ...
- 接口分离原则(Interface Segregation Principle)
接口分离原则(Interface Segregation Principle)用于处理胖接口(fat interface)所带来的问题.如果类的接口定义暴露了过多的行为,则说明这个类的接口定义内聚程度 ...
- ISP(Interface Segregation Principle),接口隔离原则
ISP(Interface Segregation Principle),接口隔离原则 它要求如下: ① 一个类对另一个类的依赖性要建立在最小接口上. ② 使用多个专门的接口比使用单一的总接口要好 ...
- 接口隔离原则(Interface Segregation Principle,ISP)
接口隔离原则: 1.使用多个专门的接口比使用单一的总接口要好. 2.一个类对另外一个类的依赖性应当是建立在最小的接口上的. 3.一个接口代表一个角色,不应当将不同的角色都交给一个接口.没有关系的接口合 ...
随机推荐
- Spring cron 表达式
前言: 最近做的项目有用到定时器,每周只在特定时间运行一次,考虑到Spring Task的简单易用性,就果断选择了,我是配置在配置文件里面,没有用注解@Scheduled,推荐配置,注解虽方便,但更改 ...
- Informatica9.6.1在Linux Red Hat 5.8上安装遇到的有关问题整理_3
3.Repository Service启动后的页面编码问题 1)错误信息: 2)原因分析及解决步骤 原因分析: informatica产品安装背后AdminConsole的Code page默认为U ...
- 【PHP入门到精通】:Ch05:字符串处理
Ch05: 字符串简介 5.1 字串说明 字符串是指由>=0个字符构成的一串字符,所以叫字符串.这里所说的字符主要包括以下几种类型:数字类型:如1, 2, 3, 4等.字母类型:如果a, b, ...
- XSS 前端防火墙(3):无懈可击的钩子
昨天尝试了一系列的可疑模块拦截试验,尽管最终的方案还存在着一些兼容性问题,但大体思路已经明确了: 静态模块:使用 MutationObserver 扫描. 动态模块:通过 API 钩子来拦截路径属性. ...
- dzzoffice注册开启
dzzoffice默认安装注册选线是关闭的,需要在“系统设置”里打开. 设置方法 开始菜单=>系统设置=>注册与访问=> 将允许用户注册选勾,选上. 然后提交保存.
- svn import 向Google code里导入初始代码
其实很简单的问题,花费了这么多时间,想把初始代码导入到Google code里,用VisaulSVN插件的Switch功能也不可以,Google code上虽然有上传,但是只能单个文件传...... ...
- 2014搜狗前端面经【B事业部】
本来就投了一份简历,后来又收到了个B事业部的面试电话,今天刚面完一面,总体感觉还是很基础的,其中一名面试官帅到不行啊!另一个也不差,真是幸胡...(sorry,跑题了...) 上来先做了份笔试题,超级 ...
- JavaScript高级程序设计(第三版)第二章 在HTML中使用JavaScript
2.1 <script>元素 <script>定义了下列6个属性: async:可选.表示应该立即下载脚本,但不应妨碍页面的其他操作,比如下载其他资源或等待加载其他脚本.只对外 ...
- 基于mapreduce的大规模连通图寻找算法
基于mapreduce的大规模连通图寻找算法 当我们想要知道哪些账号是一个人的时候往往可以通过业务得到两个账号之间有联系,但是这种联系如何传播呢? 问题 已知每个账号之间的联系 如: A B B C ...
- cocos2d-x 2.2.5 安卓工程编译的问题
原址:http://www.cocoachina.com/bbs/read.php?tid=217124 新的cocos2d-x 2.2.5 在使用Eclipse的安卓NDK 9 的编译器进行编译的时 ...