「设计模式」六大原则之四:接口隔离原则小结
Posted 小羊子说
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「设计模式」六大原则之四:接口隔离原则小结相关的知识,希望对你有一定的参考价值。
文章目录
「设计模式」六大原则系列链接:
「设计模式」六大原则之一:单一职责小结
「设计模式」六大原则之二:开闭职责小结
「设计模式」六大原则之三:里氏替换原则小结
「设计模式」六大原则之四:接口隔离原则小结
「设计模式」六大原则之五:依赖倒置原则小结
「设计模式」六大原则之六:最小知识原则小结
六大原则体现很多编程的底层逻辑:高内聚、低耦合、面向对象编程、面向接口编程、面向抽象编程,最终实现可读、可复用、可维护性。
设计模式的六大原则有:
- Single Responsibility Principle:单一职责原则
- Open Closed Principle:开闭原则
- Liskov Substitution Principle:里氏替换原则
- Law of Demeter:迪米特法则(最少知道原则)
- Interface Segregation Principle:接口隔离原则
- Dependence Inversion Principle:依赖倒置原则
把这六个原则的首字母联合起来( L 算做一个)就是 SOLID (solid,稳定的),其代表的含义就是这六个原则结合使用的好处:建立稳定、灵活、健壮的设计。
本文介绍 SOLID 中的第四个原则:接口隔离原则。它对应 SOLID 中的英文字母“I”。
1.接口隔离原则定义
接口隔离原则的英文翻译是“ Interface Segregation Principle”,缩写为 ISP。
Robert Martin 在 SOLID 原则中是这样定义它的:“Clients should not be forced to depend upon interfaces that they do not use。”直译成中文的话就是:客户端不应该被强迫依赖它不需要的接口。
其中的“客户端”,可以理解为接口的调用者或者使用者。
接口隔离的原则的目的是系统解开耦合,从而容易重构。
接口尽量小,功能尽量单一,说白了就是接口粒度要细。
2. 如何理解
“接口”这个名词可以用在很多场合中。生活中我们可以用它来指插座接口等。在软件开发中,我们既可以把它看作一组抽象的约定,也可以具体指系统与系统之间的 API 接口,还可以特指面向对象编程语言中的接口等。
理解接口隔离原则的关键,就是理解其中的“接口”二字。在这条原则中,我们可以把“接口”理解为下面三种东西:
- 一组 API 接口集合
- 单个 API 接口或函数
- OOP 中的接口概念
如果把“接口”理解为一组接口集合,可以是某个微服务的接口,也可以是某个类库的接口等。如果部分接口只被部分调用者使用,我们就需要将这部分接口隔离出来,单独给这部分调用者使用,而不强迫其他调用者也依赖这部分不会被用到的接口。
如果把“接口”理解为单个 API 接口或函数,部分调用者只需要函数中的部分功能,那我们就需要把函数拆分成粒度更细的多个函数,让调用者只依赖它需要的那个细粒度函数。
如果把“接口”理解为 OOP 中的接口,也可以理解为面向对象编程语言中的接口语法。那接口的设计要尽量单一,不要让接口的实现类和调用者,依赖不需要的接口函数。
在具体应用该原则时,可以参考下面几个规则衡量:
- 接口尽量小,但是要有限度。一个接口只服务于一个子模块或业务逻辑。
- 为依赖接口的类定制服务。只提供调用者需要的方法,屏蔽不需要的方法。
- 根据环境和业务不同的标准去考虑。
- 提高内聚,减少对外交互。让接口用最少的方法完成最多的事情。
分享一张来自 java硕哥 整理的思维导图:
3. 接口隔离原则与单一职责原则的区别
单一职责原则针对的是模块、类、接口的设计。
接口隔离原则相对于单一职责原则,一方面更侧重于接口的设计,另一方面它的思考角度也是不同的。
接口隔离原则提供了一种判断接口的职责是否单一的标准:通过调用者如何使用接口来间接地判定。
如果调用者只使用部分接口或接口的部分功能,那接口的设计就不够职责单一。
2. 举例说明
实现一个音乐播放器, 定义一个接口:
interface IMusicPlayer
//开始
void start();
//停止
void stop();
//暂停
void pause();
//复原
void resume();
//获取歌曲时长
String getSongLength();
这里满足了单一职责原则,却不满足接口隔离。
假如我们现在有个歌曲展示器 SongDisplayer,需要展示歌曲时长,那么我们也应该有个 getSongLength() 函数,我们直接实现 IMusicPlayer接口吗,实现这个接口就必须实现里面的start()等方法,但是这些方法肯定不是我需要的,也不是我应该有的,这就是问题,因为接口不够小,不干净,不纯粹,明显违背了接口隔离原则,我们就可以对接口进行拆分:
//音乐播放器就仅限于对播放的控制
interface IMusicPlayer
//开始
void start();
//停止
void stop();
//暂停
void pause();
//复原
void resume();
...
//歌曲展示器就仅限于对歌曲信息的展示
interface ISongDisplayer
//获取歌曲时长
String getSongLength();
//获取歌曲名字
String getSongName();
...
当我们实现播放器时 可以同时实现这两个接口即可,只需要展示歌曲信息的话,只需要单独实现 ISongDisplayer
即可。
public class MyPlayer implements IMusicPlayer,ISongDisplayer
//……
这样实现便更利于维护,也符合我们的接口隔离原则。
4. 小结
接口要尽量小,尽量单一,无关的接口不要冗余。粒度小,更耦合,更灵活,不会伤筋动骨。
参考:
《设计模式之美》
《重学 Java 设计模式》
《android 源码设计模式解析与实战》
以上是关于「设计模式」六大原则之四:接口隔离原则小结的主要内容,如果未能解决你的问题,请参考以下文章