1.引言
现实中有这样一种情况,火车站窗口总是挤满了排队的人,而排队的人并非都是为了买票,有的 是咨询,有的是退票,但都必须排在这一长长的队伍中,显然安排不同的窗口处理不同的业务会大大提高效率。
同样,软件设计中,胖接口强调所有的继承的类必须实现所有的方法,而有些实现的方法并非有用,这种情况对接口来说就是一种让费,而接口隔离原则(ISP,Interface Segregation Priciple)正是应对这种情况的设计标准。
2.引经据典
核心思想:使用多个小的专门接口,而不要使用一个大的总接口。
具体而言:
- 接口应该是内聚的,应该避免出现胖接口。
- 一个类对另一个类的依赖应该建立在最小的接口上,不要强迫依赖不用的方法,这是一种接口污染。
分离的手段主要有以下两种:
- 委托分离,通过增加一二新的类型来委托客户请求,隔离客户和接口的直接依赖,但会增加系统的开销。
- 多重继承分离,通过接口多继承来实现客户需求,这种方式值得推荐。
3.应用反思
//设备 public interface IDevices { //打开 void TurnOn(); //关掉 void TurnOff(); //暂停 void Pause(); } //电灯开关 public class Switch : IDevices { public void TurnOn() { Console.WriteLine("打开开关"); } public void TurnOff() { Console.WriteLine("关上开关"); } public void Pause() { throw new NotImplementedException(); } }
上面的接口 有3个方法,但是 电灯开关 并没有这个暂停功能,所以实现它只是抛出一个异常,因为这个Pause方法,电灯开关并不需要,是多余的,因此IDevices接口相对于Switch 是一个胖接口,我们应该把这个胖接口分离。
//设备 public interface IDevices { //打开 void TurnOn(); //关掉 void TurnOff(); } //播放器 public interface IPlay : IDevices { //暂停 void Pause(); } //电灯开关 public class Switch : IDevices { public void TurnOn() { Console.WriteLine("打开开关"); } public void TurnOff() { Console.WriteLine("关上开关"); } } //百度影音 public class BaiduPlayer : IPlay { public void Pause() { Console.WriteLine("播放暂停"); } public void TurnOn() { Console.WriteLine("打开开始播放"); } public void TurnOff() { Console.WriteLine("播放介绍关闭"); } }
我们也可以把 Iplay不继承 IDevices,只有一个 pase方法,BaiduPlayer 实现两个接口。
4.规则建议
- 将功能相近的接口合并,可能造成接口污染,实现内聚的接口才是接口设计的基本原则。
- 接口隔离原则能够保证系统的扩展和修改的影响不会扩展到系统的其他部分,一定程度上保证了开放封闭原则。
作者:Qlin
出处:http://www.cnblogs.com/qqlin/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。