精通接口隔离原则,轻松实现高内聚、低耦合架构

来源:mikechen的互联网架构

接口隔离原则是实现高内聚、低耦合系统的基石。

接口隔离原则旨在解决接口设计的问题。通过将大接口拆分成多个小接口,让每个接口专注服务于一个子模块或业务逻辑,让系统更加灵活、可维护。

例如:家中的智能家居系统,有电视、电脑、窗帘、电灯等。

图左:遵循接口隔离

对具有相同功能的设备,配备独立遥控器,每个遥控器专注提供特定设备的控制按钮。

如果需要开灯,就用灯光遥控器,非常便捷。更改某个设备,也不会影响其他设备。

图右:不遵循接口隔离

通过一个多功能的遥控器,来控制所有设备

  • 遥控器按钮太多,很难快速找到需要的功能。


  • 按钮之间耦合度高。修改任一设备,都可能牵一发而动全身。


  • 要同时处理多种设备的功能,职责混杂,违背单一职责原则。


本文,我们深入接口隔离原则,力求通过图解、源码剖析到位

大家好,我是 mikechen。

接口隔离是良好架构设计的基石,面试常考,非常重要。
为方便大家系统学习,我已将本文归纳到《阿里架构师进阶专题合集》。
需要的同学,拉到文末获取。

01
   接口隔离原则的定义

接口隔离原则( ISP),英文全称 Interface Segregation Principle 。

接口隔离原则是指不应该强行要求客户端依赖于它们不用的接口,类之间的依赖应该建立在最小的接口上面。

简单理解:

  • 客户端需要什么接口,就提供什么接口,不需要的就不依赖。


  • 将大接口拆分成多个小接口,每个接口只专注服务于一个子模块或业务逻辑。


  • 使用抽象类或默认方法,来减少接口的改动对原有代码的影响。


02
  接口隔离原则的由来

接口隔离原则的提出,是为了解决接口过大所带来的问题,提高系统的灵活性和可维护性。

  • 如果客户端依赖了不需要的接口,将增加客户端和接口之间的耦合度,与“高内聚、低耦合”的思想相矛盾。

  • 如果一个接口中包含了很多不相关的方法,要实现这个接口的类,就必须实现所有的方法。


03
  接口隔离原则示例

在软件设计最初,我们的想法是将相同功能的方法放在同一个接口里面。

理论上来说,这貌似没错,我们来看看如何设计。

例如:

类 A 通过接口 I 依赖类 B,类 C 通过接口 I 依赖类 D。

那么,对于类 A 和类 B 来说,接口 I 不是最小接口,则类 B 和类 D 必须去实现它们不需要的方法。

如图:

类 A 依赖接口 I 中的方法 1、方法 2、方法 3,类 B 是对类 A 依赖的实现。

类 C 依赖接口 I 中的方法 1、方法 4、方法 5,类 D 是对类 C 依赖的实现。

对于类 B 和类 D 来说,虽然都有用不到的方法(红色字体),但由于实现了接口 I,所以也必须要实现这些用不到的方法。

代码示例:































interface I {    public void method1();    public void method2();    public void method3();    public void method4();    public void method5();}
class A{    public void depend1(I i){        i.method1();    }    public void depend2(I i){        i.method2();    }    public void depend3(I i){        i.method3();    }}
class B implements I{    public void method1() {        System.out.println("类B实现接口I的方法1");    }    public void method2() {        System.out.println("类B实现接口I的方法2");    }    public void method3() {        System.out.println("类B实现接口I的方法3");    }

对于类 D 来说,method2 和 method3 不是必需的。

但是,由于接口 A 中有这两个方法,即使它们没有作用,在实现时,也要同时实现这两个方法。

























    public void method2() {}    public void method3() {}
   public void method4() {        System.out.println("类D实现接口I的方法4");    }    public void method5() {        System.out.println("类D实现接口I的方法5");    }}
public class Client{    public static void main(String[] args){        A a = new A();        a.depend1(new B());        a.depend2(new B());        a.depend3(new B());
       C c = new C();        c.depend1(new D());        c.depend2(new D());        c.depend3(new D());    }}

当接口过多时,对依赖于它的类来说,接口中的方法有没有用,实现类中都必须去实现这些方法。

这样的架构设计很不合理,明显与“高内聚、低耦合”的思想相悖。

在程序设计中,依赖几个专用的接口,要比依赖一个综合的接口更灵活。

为了遵循接口隔离原则,我们将一个庞大的接口,拆分为 3 个专用的接口。

例如,将接口 I 拆分为接口 I1、接口 I2、接口 I3。

代码示例:






























































interface I1 {    public void method1();}
interface I2 {    public void method2();    public void method3();}
interface I3 {    public void method4();    public void method5();}
class A{    public void depend1(I1 i){        i.method1();    }    public void depend2(I2 i){        i.method2();    }    public void depend3(I2 i){        i.method3();    }}
class B implements I1, I2{    public void method1() {        System.out.println("类B实现接口I1的方法1");    }    public void method2() {        System.out.println("类B实现接口I2的方法2");    }    public void method3() {        System.out.println("类B实现接口I2的方法3");    }}
class C{    public void depend1(I1 i){        i.method1();    }    public void depend2(I3 i){        i.method4();    }    public void depend3(I3 i){        i.method5();    }}
class D implements I1, I3{    public void method1() {        System.out.println("类D实现接口I1的方法1");    }    public void method4() {        System.out.println("类D实现接口I3的方法4");    }    public void method5() {        System.out.println("类D实现接口I3的方法5");    }}

每个类只需实现与其功能相关的接口,不需要的方法则不用去实现,极大提高了系统的可维护性和灵活性。

需要注意的是,对接口拆分要合理:

1)接口拆分应该尽量小,且专注于一个明确定义的功能领域。

2)接口设计避免过大或过小。过大可能导致实现类需要实现大量不必要的方法;而过小可能导致需要实现的接口数量过多,系统设计会变得很复杂。

看到这里,是不是觉得接口隔离和单一职责有些相似?

其实不然,下面介绍。


04
  接口隔离原则和单一职责原则的区别

从功能上来看,接口隔离和单一职责确实有一定的相似性。

两者都是为了降低它们之间的耦合性,体现了封装的思想。

但是,两者的侧重点却不同:

  • 单一职责原则:关注类的职责,针对程序实现和细节,偏向于业务;


  • 接口隔离原则:关注对接口依赖的隔离,针对抽象和程序整体框架的构建,偏向于架构设计。

 

单一职责原则的详解篇:吃透单一职责原则,100倍效果提升代码质量

两篇一定要结合看,更容易融会贯通。


总结
  

接口隔离原则通过将大接口拆分成多个小接口,让每个接口只专注服务于一个子模块或者业务逻辑,让系统更加灵活、可维护。

接口隔离原则的核心是接口细化,接口细化要合理,结合系统的实际需求,以适度设计为前提,既小而精确。

建议收藏备用,划走就再也找不到了。

接口隔离原则是良好架构设计的基石,社/校招面试也常问,非常重要。

请使用浏览器的分享功能分享到微信等