Interface Segregation Principle
What 什么是接口隔离原则?
定义:客户端不应该依赖那些它不需要的接口
1.当一个接口太大的时候需要将它分割成一些更小的接口,使用该接口的客户端仅需要知道和它先关的接口
2.每一个接口应该承担一种相对独一的角色,不干不该干的事,该干的事都要干。
接口的两种定义:
1.第一种接口是指该类所持有的的方法的集合,是一种逻辑上的抽象。当想要对该类进行某些操作的时候,需要调用这些方法。
当把接口理解为成一个类型说提供的所有方法特征的集合的时候,这就是一种逻辑上的概念,接口的划分会带来类型的划分,可以把接口理解成角色,一个接口只能代表一个角色,每个角色都有他特定的一个接口。此时这个原则可以叫角色隔离原则。
2.第二种接口是指某种语言具体的“接口”,有严格的定义和结构。如在C#和JAVA语言中的interface。
当把接口理解为特定语言的接口,那么接口隔离原则表达的意思仅仅是提供客户端需要的行为,客户端不需要的行为则需要隐藏起来,所以我们只需要为客户端提供尽可能小的接口,不要提供大的总接口。
Why 为什么要使用接口隔离原则?
在面向对象语言中,实现一个接口需要定义该接口中的所有方法,因此大接口用起来分不方便,增加了无用代码,为了使接口的职责单一,需要将大接口中的方法根据职责不同分别放在不同的小接口中,另一方面,接口应该尽量细化,同时接口中的方法尽可能量小,每一个接口只包含一个客户端(子模块,业务逻辑类)所需要的方法,为不同的客户端定制提供宽窄不同的接口。
How 如何使用接口隔离原则?
示例
某软件公司开发人员针对CRM系统的客户数据显示模块设计了如图所示的ICustomerDataDisplay接口,其中方法readData()用于冲文件读取数据,方法tranformToXML()用于将数据转换成XML格式,方法createChart()用于创建图标,方法displayChart()用于显示图表,方法createReport()用于创建文字报表,方法displayReport()用于显示文字报表。
在实际使用过程中发现该接口很不灵活,例如:如果一个具体的数据显示类无需进行数据转换(源文件就是XML格式的)但是由于实现了该接口,不得不实现其中声明的其他方法,否则程序编译就是出错。
现在需要使用接口隔离原则进行重构。
在ICustomerDataDisplay接口中定义了太多方法,该接口承担了太多的职责,一方面这将会导致,在实现这个接口的具体实现类中,不得不定义接口中的所有方法,灵活性较差,如果出现大量的空方法,这将导致系统出现大量的无用代码,,影响代码质量。另一方面方面对于客户端针对大接口进行编程,这将一定程度上破坏程序的封装性,客户端看到了不该看到的方法。
所以需要将接口按照单一职责和接口隔离原则进行重构,将大接口按照职责划分为小接口,每一个接口只包含一个客户端所需要的方法即可。
如图:
结论
在使用接口隔离原则的时候需要注意控制接口的粒度,接口不能太大,接口不能太小。如果接口太小将会到中系统中接口泛滥。如果接口太大将违背接口隔离原则。所以一般在进行程序设计的时候,在接口中仅包含为某一类客户端定制的方法即可,不应该强迫客户端去依赖那些他们不需要的方法。