背景:
在实际的业务开发中往往会因为初期的设计不合理,使得接口中定义了众多方法,而这些接口在实现类中又并不需要全部实现。这样的接口定义是不利于扩展的,也将对后期的维护带来困扰,我们将通过示例来演示符合接口隔离原则带来的好处。
概念:
- 接口隔离原则的定义: 客户端不应该被迫依赖于它不适用的方法
- 接口隔离原则的要求: 将臃肿庞大的接口拆分成更小的和更加具体的接口,保证客户端只得到自己需要的方法
案例:
需求:
- 设计HomePage页面
- 功能支持点击事件:可以跳转到EditPage页面
- 功能支持双击事件:可以双击后退出程序
- 设计EditPage页面
- 功能支持双击事件:可以双击后选择文本
- 功能支持长按事件:可以长按后选择全部文本
违反原则实现:
定义点击相关的监听接口
interface OnClickListener { onClick(): void; onDoubleClick(): void; onLongPress(): void; }
HomePage实现:
class HomePage implements OnClickListener { onClick(): void { console.log("触发点击事件进入编辑页面"); } onDoubleClick(): void { console.log("触发双击事件退出页面"); } onLongPress(): void { // 无相关需求,空实现 } }
EditPage实现:
class EditPage implements OnClickListener { onClick(): void { // 无相关需求,空实现 } onDoubleClick(): void { console.log("触发双击事件,选择文本"); } onLongPress(): void { console.log("触发长按事件,选择文本"); } }
说明:
通过上面的示例可以看得出没有页面都存在一个与自己无关的方法需要实现,我们还需要在代码或维护文档中注明哪些方法必须实现哪些方法又不用实现,既不符合设计模式也不利于维护。
符合原则实现:
将要原来的接口进行细粒度拆分:
拆分后的接口可以由需要页面有选择的进行自由组合来实现
interface OnClickListener { onClick(): void; } interface OnDoubleClickListener { onDoubleClick(): void; } interface OnLongPressListener { onLongPress(): void; }
HomePage实现:
class HomePage implements OnClickListener, OnDoubleClickListener { onClick(): void { console.log("触发点击事件进入编辑页面"); } onDoubleClick(): void { console.log("触发双击事件退出页面"); } }
EditPage实现:
class EditPage implements OnDoubleClickListener, OnLongPressListener { onDoubleClick(): void { console.log("触发双击事件,选择文本"); } onLongPress(): void { console.log("触发长按事件,选择文本"); } }
说明:
我们可以看到符合设计模式的代码将变得更加灵活,在Android开发中关于事件的一些监听接口也是同样使得。再比如说通过Sql来操作数据库的时候,对数据库的操作往往都包括,打开数据库,连接数据库,关闭数据库,往数据库添加数据,删除数据,更新数据和查询数据,同样都是对数据库的操作但往往这些操作会大致的分成两类来进行设计,更细分的话查询数据也可能会单独拆分。按照合理的设计进行符合接口隔离原则的拆分对实现代码高内聚,低耦合将变得尤为重要。