"围观"设计模式(4)--接口隔离原则(ISP,Interface Segregation Principle)
2016-04-17 13:49
369 查看
接口隔离原则(英语:interface-segregation principles, 缩写:ISP)指明没有客户(client)应该被迫依赖于它不使用方法。接口隔离原则(ISP)拆分非常庞大臃肿的接口成为更小的和更具体的接口,这样客户将会只需要知道他们感兴趣的方法。这种缩小的接口也被称为角色接口(role interfaces)。接口隔离原则(ISP)的目的是系统解开耦合,从而容易重构,更改和重新部署。----WIKIPEDIA
个人对于接口隔离原则的理解是:
设计接口的时候,尽量保证实现接口的那些类尽可能一致的包含着接口中的方法,避免过多的设计了接口中的方法,导致其实现类中需要实现多个完全没有用处的方法(会造成代码的冗余和混乱)。
下面看这样一个例子,理解一下上面我对于接口隔离原则(Interface Segregation Principle)理解的这几句话:
这里,我们假设Dog具有的行为有eatFood、run,Bird具有的行为有eatFood和sing、fly。
Dog实现这个Common接口
Bird类实现这个接口
这样设计有什么问题?
1. 一个接口中封装了太对的方法,导致Dog和Bird这两个类中必须实现一些无用的方法。
2. 这样的接口稳定性较差,如果Dog需要增加一个方法的话,那么Bird这个实现类中也要相应的实现这个方法(当然方法体内是空的,但是必须要实现的)。
3. 编码混乱,导致修改时难度增加(需要自己去区分开哪些是这个类中的方法,哪些是另外的一个类中的方法,这样额外增加了工作量)。
应该怎么设计?
我自己的一个设计
将公共的部分抽取出来单独放在一个接口中,自己独有的行为放在相应的接口中,通过独有的这个接口去继承公共的接口,这样的话,就能很好的起到接口的隔离的作用。如果这个时候,需求变了,我有一个动物只能吃饭,那么好,根据这个设计直接去实现Common接口,实现其eatFood方法。OK,其余的类和方法都不需要变更。当然这个地方并不一定所有的东西都有eatFood这样的行为,那么这个地方我只是举了这样的一个例子,公共的部分是eatFood,那么在实际的使用中,可能是别的相关的行为等。那样的话需要自己去对他们进行抽取。
这里只呈现一部分代码,主要是接口部分的代码,完整的代码,包括以后的设计模式的代码,我会在更新博客的同时,上传到我的GitHub上,希望大家可以多多支持与交流。
下载完整代码:下载完整代码
个人对于接口隔离原则的理解是:
设计接口的时候,尽量保证实现接口的那些类尽可能一致的包含着接口中的方法,避免过多的设计了接口中的方法,导致其实现类中需要实现多个完全没有用处的方法(会造成代码的冗余和混乱)。
下面看这样一个例子,理解一下上面我对于接口隔离原则(Interface Segregation Principle)理解的这几句话:
这里,我们假设Dog具有的行为有eatFood、run,Bird具有的行为有eatFood和sing、fly。
public interface Common { public void eatFood(); public void run(); public void sing(); public void fly(); }
Dog实现这个Common接口
public class Dog implements Common{ @Override public void eatFood() { System.out.println("Dog 吃狗粮!"); } @Override public void run() { System.out.println("Dog 逮老鼠!"); } // 下面这两个接口不是狗的特性不需要实现,这里注意体会下这样的一个架构的不合理性。 @Override public void sing() { } @Override public void fly() { } }
Bird类实现这个接口
public class Bird implements Common{ @Override public void eatFood() { System.out.println("Bird 吃粮食!"); } // 这里run不是小鸟的特性也不需要实现,体会这样设计的弊端 @Override public void run() { } @Override public void sing() { System.out.println("Bird 叽叽喳喳唱!"); } @Override public void fly() { System.out.println("Bird 飞走了!"); } }
这样设计有什么问题?
1. 一个接口中封装了太对的方法,导致Dog和Bird这两个类中必须实现一些无用的方法。
2. 这样的接口稳定性较差,如果Dog需要增加一个方法的话,那么Bird这个实现类中也要相应的实现这个方法(当然方法体内是空的,但是必须要实现的)。
3. 编码混乱,导致修改时难度增加(需要自己去区分开哪些是这个类中的方法,哪些是另外的一个类中的方法,这样额外增加了工作量)。
应该怎么设计?
我自己的一个设计
将公共的部分抽取出来单独放在一个接口中,自己独有的行为放在相应的接口中,通过独有的这个接口去继承公共的接口,这样的话,就能很好的起到接口的隔离的作用。如果这个时候,需求变了,我有一个动物只能吃饭,那么好,根据这个设计直接去实现Common接口,实现其eatFood方法。OK,其余的类和方法都不需要变更。当然这个地方并不一定所有的东西都有eatFood这样的行为,那么这个地方我只是举了这样的一个例子,公共的部分是eatFood,那么在实际的使用中,可能是别的相关的行为等。那样的话需要自己去对他们进行抽取。
public interface Common { // 抽取出公共的方法 public void eatFood(); }
public interface DogInter extends Common { public void run(); }
public interface BirdInter extends Common{ public void sing(); public void fly(); }
这里只呈现一部分代码,主要是接口部分的代码,完整的代码,包括以后的设计模式的代码,我会在更新博客的同时,上传到我的GitHub上,希望大家可以多多支持与交流。
下载完整代码:下载完整代码