前置知识
- 了解单一职责原则
- 熟悉使用面向对象中的接口
- 有项目开发经历
前言
今天为大家带来的依旧是 设计原则 的知识: 接口隔离原则
首先老规矩,先上百度的定义
定义:
一个类对另外一个类的依赖性应当是建立在最小的接口上的。
一个接口代表一个角色,不应当将不同的角色都交给一个接口。没有关系的接口合并在一起,形成一个臃肿的大接口,这是对角色和接口的污染。
英文版的解释是这样的
Clients should not be forced to depend upon interfaces that they do not use.
结合上下两个定义,我们可以得出。接口隔离原则的意思大致为:服务调用者不该依赖与自己业务无关的接口
这时候我们会发现,这个定义似乎和 单一职责原则 相类似。单一职责所说的是 一个类或者模块只承担一个职责 ,而接口隔离也是强调不依赖与自身无关的东西。这两者确实是十分类似,但是本质上又是不同的。
具体哪里不同,我们先不着急回答,我们先看看接口隔离原则的具体应用和其优势。深入了解之后,我们就能知晓两者的不同了。
如何进行接口隔离?
对于接口的隔离,我们首先要明确我们所描述的接口是什么。
在技术圈,我们有很多种接口,除去物理接口不谈,我们有 SDK、JDK 里面的给我们调用的函数调用接口,有网络的 API接口,有面向对象定义的接口特性,甚至我们说写的函数也可称之为接口。
这么多的接口,事实上都适合于应用 接口隔离原则 ,这些称之为接口的各种特性,他们事实上都可认定为一种协议。而对协议做单一化的规范,就是 接口隔离原则的任务所在。
下面让我们从 面向对象的接口 来举例说明,我们该如何进行接口隔离
假设我们有两个类,学生类和打字员类,学生要实现 homeWork()
方法,打字员要实现 printWork()
方法
public interface PersonWork{ void homeWork(); void printWork(); } public class Student implements PersonWork{ ... @Override public void homeWork(){ ... } @Override public void printWork(){ //空实现 } } public class PrintPerson implements PersonWork{ ... @Override public void homeWork(){ //空实现 } @Override public void printWork(){ ... } } 复制代码
上述代码中,我们写了一个 PersonWork 接口,包括了两个抽象方法,然后对应的学生类和打字员类都来实现这个接口。
我们发现以上代码有以下的缺点
- 不利于接口拓展,修改了一个接口,就得修改多处原本已实现的地方
- 实现类继承了无用的方法,导致做无用工
- 影响代码可读性,一个大而全的接口类,无法表明清楚接口的特性
所以我们可以进行如下改造,使得符合 接口隔离原则
public interface PersonHomeWork{ void homeWork(); } public interface PersonPrintWork{ void printWork(); } public class Student implements PersonHomeWork{ ... @Override public void homeWork(){ ... } } public class PrintPerson implements PersonPrintWork{ ... @Override public void printWork(){ ... } } 复制代码
我们将上述的对应不同功能类的接口独立开,然后需要实现对应功能的类再实现对应的接口。这样子就符合了 接口隔离原则 ,
上述的3个缺点也顺应的解决了。当我们想要拓展的时候,直接定义一个新的接口,进行接口多继承即可。
接口隔离和单一职责的区别
通过上文,想必你已清楚接口隔离所对应的范围与单一职责是不同的。那么我们可以总结出以下的不同点
- 应用范围的不同,接口隔离针对的是接口职责是否单一,而单一职责针对的是类或者模块
- 判断对象的不同,接口隔离原则判断是否单一的对象是接口调用者,而单一职责原则判断是否单一的对象是较为抽象的业务以及其自身
到此,我们就回答完了前面抛出的问题,也深入理解了该原则