接口隔离原则
基本介绍
Interface Segregation Principle(ISP)接口隔离原则
Clients should not be forced to depend upon interfaces that they do not use
客户端不应该请破依赖它不需要的接口
如何理解"接口隔离原则"?
- 如果把接口理解为一组接口集合,可以是某个微服务的接口,也可以是某个类库的接口等
- 如果把接口理解为单个API接口或函数,部分调用者只需要函数中的部分功能,那我们就需要把函数拆分成粒度更细的多个函数,让调用者只依赖它需要的那个细粒度函数
- 如果接口理解为OOP中接口,也可以理解为面向对象编程语言中的接口语法。那接口的设计要尽量单一,不要让接口实现类和调用者,依赖不需要的接口函数。
接口隔离原则和单一职责原则对比
- 接口隔离原则更侧重于接口的设计
- 接口隔离原则提供了一种判断接口的职责是否单一的标准,通过调用者如何使用接口来间接地判定。
应用示例
//接口
interface GlobalInterface {
void operator01();
void operator02();
void operator03();
void operator04();
void operator05();
}
class A {
//A 类通过接口Interface1 依赖(使用) B类,但是只会用到1,2,3方法
public void depend1(GlobalInterface globalInterface) {
globalInterface.operator01();
}
public void depend2(GlobalInterface globalInterface) {
globalInterface.operator02();
}
public void depend3(GlobalInterface globalInterface) {
globalInterface.operator03();
}
}
class B implements GlobalInterface {
public void operator01() {
System.out.println("B 实现了 operator1");
}
public void operator02() {
System.out.println("B 实现了 operator2");
}
public void operator03() {
System.out.println("B 实现了 operator3");
}
public void operator04() {
System.out.println("B 实现了 operator4");
}
public void operator05() {
System.out.println("B 实现了 operator5");
}
}
class C { //C 类通过接口Interface1 依赖(使用) D类,但是只会用到1,4,5方法
public void depend1(GlobalInterface globalInterface) {
globalInterface.operator01();
}
public void depend4(GlobalInterface globalInterface) {
globalInterface.operator04();
}
public void depend5(GlobalInterface globalInterface) {
globalInterface.operator05();
}
}
class D implements GlobalInterface {
public void operator01() {
System.out.println("D 实现了 operator01");
}
public void operator02() {
System.out.println("D 实现了 operator02");
}
public void operator03() {
System.out.println("D 实现了 operator03");
}
public void operator04() {
System.out.println("D 实现了 operator04");
}
public void operator05() {
System.out.println("D 实现了 operator05");
}
}
分析:GlobalInterface 中定义了很多方法,在类A,B,C,D中引入了GlobalInterface中不需要的方法,从而说明GlobalInterface方法的定义粒度太大,需要进行拆分
// 接口1
interface Interface1 {
void operation1();
}
// 接口2
interface Interface2 {
void operation2();
void operation3();
}
// 接口3
interface Interface3 {
void operation4();
void operation5();
}
class A { // A 类通过接口Interface1,Interface2 依赖(使用) B类,但是只会用到1,2,3方法
public void depend1(Interface1 i) {
i.operation1();
}
public void depend2(Interface2 i) {
i.operation2();
}
public void depend3(Interface2 i) {
i.operation3();
}
}
class B implements Interface1, Interface2 {
public void operation1() {
System.out.println("B 实现了 operation1");
}
public void operation2() {
System.out.println("B 实现了 operation2");
}
public void operation3() {
System.out.println("B 实现了 operation3");
}
}
class C { // C 类通过接口Interface1,Interface3 依赖(使用) D类,但是只会用到1,4,5方法
public void depend1(Interface1 i) {
i.operation1();
}
public void depend4(Interface3 i) {
i.operation4();
}
public void depend5(Interface3 i) {
i.operation5();
}
}
class D implements Interface1, Interface3 {
public void operation1() {
System.out.println("D 实现了 operation1");
}
public void operation4() {
System.out.println("D 实现了 operation4");
}
public void operation5() {
System.out.println("D 实现了 operation5");
}
}
分析:实际项目中,可以根据功能进行分类,尽可能避免不需要的接口被引用到实现类中。
例如:在后台管理服务的接口,被前端客户服务调用,这种极有可能出现安全问题。