一.定义
1.核心思想
接口隔离原则(Interface Segregation Principle,ISP)要求程序员尽量将臃肿庞大的接口拆分成更小的和更具体的接口,
让接口中只包含客户感兴趣的方法,不应该强迫客户程序依赖它们不需要使用的方法, 即不应该把所有的操作都封装到一个接口中。
一个类对另一个类的依赖应该建立在最小接口上;(接口方法最少,系统有更高的灵活性)
单一职责 与 接口隔离原则的异同
接口隔离原则和单一职责都是为了提高类的内聚性、降低它们之间的耦合性,体现了封装的思想,但两者是不同的:
1. 单一职责注重的是职责,而接口隔离原则注重的是对接口依赖的隔离;
2. 单一职责主要是约束类,它针对的是程序中的实现和细节;接口隔离原则主要约束接口,主要针对抽象和程序整体框架的构建;
2.注意事项
*1. 接口尽量小:这为了保证一个接口只服务于一个子模块或者业务逻辑;
*2. 接口高内聚:高内聚是对内高度依赖,对外尽可能隔离,即一个接口内部声明的方法相互之间都与某个子模块相关;
*3. 一个接口中的所有方法尽可能让其所有子实现类都实现,如果有子实现类,没有实现其方法,就要拆分隔离接口;
*4. 接口设计是有限度的:要观其 复杂度 而定;
3.总结
要为各个类建立它们需要的专用接口,而不要试图去建立一个很庞大的接口供所有依赖它的类去调用;
二.优点
接口隔离原则是为了约束接口、降低类对接口的依赖性,遵循接口隔离原则有以下5个优点:
1. 将臃肿庞大的接口分解为对个粒度小的接口,可以预防外来变更的扩散,提高系统的灵活性和可维护性;
2. 接口隔离提高了系统的内聚性,减少了对外交互,降低了系统的耦合性;
3. 接口的粒度大小要定义合理,保证系统的稳定性;定义较小,会造成接口数量过多,使设计复杂化,
定义太大,灵活性降低,无法提供定制服务,给整体项目带来无法预料的风险;
4. 使用多个专门的接口还能体现对象的层次,因为可通过接口的实现对总接口定义;
5. 能减少项目工程中的代码冗余,过大的大接口里通常放置许多不用的方法,当实现这个接口时,被迫设计冗余的代码;
三.实现方法
在具体应用接口隔离原则时,应该根据以下几个规则来衡量
1. 接口尽量小,但是要有限度,一个接口只服务于一个子模块或业务逻辑;
2. 为依赖接口的类定制服务,只提供调用者需要的方法,屏蔽不需要的方法;
3. 了解环境,拒绝盲从,每个项目或产品都有选定的环境因素,环境不同,接口拆分的标准就不同深入了解业务逻辑;
4. 提高内聚,减少对外交互,使接口用最少的方法去完成最多的事情;
四.代码示例
/**
* 接口分离原则
* 类A通过接口interface1依赖类B, A中只会使用接口的1,2,3三个方法
* 类C通过接口Interface1依赖类D, C中只会使用接口的1,4,5,三个方法
* interface1包括 隔离前 隔离后
* operation1():void --Interface1
* operation2():void --Interface2
* operation3():void /
* operation4():void --Interface3
* operation5():void /
* 通过接口分离原则, 将Interface1 分解成最小要依赖的接口,将用不到的接口拆成都要被实现的;
*/
public class Segregation {
public static void main(String[] args) {
A a = new A();
B b = new B();
//A类通过接口去依赖(使用)B类
a.depend1(b);
a.depend2(b);
a.depend3(b);
C c = new C();
D d = new D();
//C类通过接口去依赖(使用)D类
c.depend1(d);
c.depend4(d);
c.depend5(d);
}
}
public interface Interface1 {
void operation1();
}
public interface Interface2 {
void operation2();
void operation3();
}
public interface Interface3 {
void operation4();
void operation5();
}
public class A {
//A类用通过接口Interface1 依赖(使用) B类, 只会用到Interface1的1,2,3方法
public void depend1(Interface1 interface1) {
interface1.operation1();
}
public void depend2(Interface2 interface2) {
interface2.operation2();
}
public void depend3(Interface2 interface2) {
interface2.operation3();
}
}
public class B implements Interface1,Interface2{
@Override
public void operation1() {
System.out.println("B中实现了=====operation1====");
}
@Override
public void operation2() {
System.out.println("B中实现了=====operation2====");
}
@Override
public void operation3() {
System.out.println("B中实现了=====operation3====");
}
}
public class C {
//C类用通过接口Interface1 依赖(使用) D类, 只会用到Interface1的1,4,5方法
public void depend1(Interface1 interface1) {
interface1.operation1();
}
public void depend4(Interface3 interface3) {
interface3.operation4();
}
public void depend5(Interface3 interface3) {
interface3.operation5();
}
}
public class D implements Interface1,Interface3{
@Override
public void operation1() {
System.out.println("D中实现了====operation1====");
}
@Override
public void operation4() {
System.out.println("D中实现了===operation4====");
}
@Override
public void operation5() {
System.out.println("D中实现了===operation5====");
}
}