• 设计原则之【接口隔离原则】


    设计原则是指导我们代码设计的一些经验总结,也就是“心法”;面向对象就是我们的“武器”;设计模式就是“招式”。

    以心法为基础,以武器运用招式应对复杂的编程问题。

    来吧,通过生活中一个小场景,一起系统学习这6大设计原则。

    SOLID原则--SRP单一职责原则

    SOLID原则--OCP开放封闭原则

    SOLID法则--LSP里式替换原则

    SOLID原则--ISP接口隔离原则

    SOLID原则--DIP依赖反转原则

    LOD迪米特法则

    和表妹去逛超市...

    表妹:哥啊,我想买酸奶😄

    我:买,问题不大。

    表妹:他家的酸奶都在搞活动,买酸奶送鸡蛋。

    我:那不挺好嘛?把鸡蛋也一起买啦。

    表妹:可是我家还有好多鸡蛋......


    你看,这种“捆绑式消费”,不就类似违反了我们软件设计中的“接口隔离原则”嘛?鸡蛋并不是我们想要的,但是它却跟我们想要的酸奶绑在一起,酸奶就变得“臃肿”了。

    客户端不应该强迫依赖它不需要的接口。其中的“客户端”,可以理解为接口的调用者或使用者。

    如何理解“接口”?

    理解“接口隔离原则”的重点是理解其中的“接口”二字。这里有三种不同的理解:

    • 如果把“接口”理解为一组接口集合,可以是某个微服务的接口,也可以是类库的接口等。如果部分接口只被部分调用者使用,我们就需要将这部分接口隔离出来,单独给这部分调用者使用,而不强迫其他调用者也依赖这部分不会被用到的接口。

    • 如果把“接口”理解为单个API接口或函数,部分调用者只需要函数中的部分功能,那我们就需要把函数拆分成粒度更细的多个函数,让调用者只依赖它需要的那个细粒度函数。

    • 如果把“接口”理解为OOP中的接口,也可以理解为面向对象编程语言中的接口语法。那接口的设计要尽量单一,不要让接口的实现类和调用者,依赖不需要的接口函数。

    那么,接下来,我们从面向对象编程语言中的接口语法的角度来学习一下“接口隔离原则”。

    我们一起来看“美女”,一般来说,长得好看的,身材不错的,气质出众的都可以成为美女。

    所以,我们定义了一个IPettyGirl接口,显示美女的这几个特征。PettyGirl是该接口的实现类。

    复制代码
     1 // 美女接口
     2 public interface IPettyGirl {
     3     // 要有姣好的面孔
     4     public void goodLooking();
     5     // 要有好身材
     6     public void niceFigure();
     7     // 要有气质
     8     public void greatTemperament();
     9 }
    10 11 // 接口的实现类
    12 public class PettyGirl implements IPettyGirl {
    13     private String name;
    14 15     public PettyGirl(String  name){
    16        this.name = name;
    17     }
    18 19     // 脸蛋漂亮
    20     public void goodLooking() {
    21          System.out.println(this.name + "---脸蛋很漂亮!");
    22     }
    23 24     // 气质要好
    25     public void greatTemperament() {
    26           System.out.println(this.name + "---气质非常好!");
    27     }
    28 29     // 身材要好
    30     public void niceFigure() {
    31           System.out.println(this.name + "---身材非常棒!");
    32     }
    33 }
    复制代码

    我们仔细想一下,长得好看,拥有好的身材,而且气质还好的,当然是“美女”,甚至还是“女神”, “神仙小姐姐”,因为简直是无可挑剔。这是所有人心目中的评判标准。

    但是,我们每个人都会有自己不同的审美标准。假如,隔壁老王就认为“美女”应该是具有好看的皮囊,长得好看,身材好。老李就喜欢有趣的灵魂,认为气质好的才是“美女”。

    那么,这样看来,IPettyGirl接口的设计就显得比较臃肿了,因为太宽泛了,其实每个人的审美标准都不同。所以,我们将该接口进行拆分,如下:

    复制代码
     1 // IGoodBodyGirl 好看的皮囊
     2 public interface IGoodBodyGirl {
     3      // 要有姣好的面孔
     4      public void goodLooking();
     5      // 要有好身材
     6      public void niceFigure();
     7 }
     8  9 // IGreatTemperamentGirl 有趣的灵魂
    10 public interface IGreatTemperamentGirl {
    11      // 要有气质
    12      public void greatTemperament();
    13 }
    14 15 // PettyGirl1 老王心目中的美女---长得好看,身材好
    16 public class PettyGirl1 implements IGoodBodyGirl {
    17      private String name;
    18 19      public PettyGirl1(String _name){
    20         this.name = _name;
    21   }
    22 23      // 脸蛋漂亮
    24      public void goodLooking() {
    25         System.out.println(this.name + "---脸蛋很漂亮!");
    26      }
    27 28      // 身材要好
    29      public void niceFigure() {
    30         System.out.println(this.name + "---身材非常棒!");
    31      }
    32 }
    33 34 // PettyGirl2 老李心目中的美女---气质好
    35 public class PettyGirl2 implements IGreatTemperamentGirl {
    36      private String name;
    37      public PettyGirl2(String _name) {
    38         this.name = _name;
    39      }
    40     
    41      // 气质要好
    42      public void greatTemperament() {
    43         System.out.println(this.name + "---气质非常好!");
    44      }
    45 }
    复制代码

    你看,这样的设计,是不是更加灵活,易扩展了?

    假如,有些人认为心灵美的人,才叫“美女”。我们只需扩展如下代码,而无需改动之前的代码。

    复制代码
     1 // IMindBeautyGirl 心灵美
     2 public interface IMindBeautyGirl {
     3     // 心灵美
     4     public void mindbeauty();
     5 }
     6  7 // PettyGirl3 心灵美的美女
     8 public class PettyGirl3 implements IMindBeautyGirl {
     9     private String name;
    10     public PettyGirl3(String _name) {
    11         this.name = _name;
    12     }
    13     
    14     // 心灵美
    15     public void mindbeauty() {
    16         System.out.println(this.name + "---心灵美!");
    17     }
    18 }
    复制代码

    但是,如果按照IPettyGirl这个接口设计的话,我们不但要改动IPettyGirl这个接口,还要改每一个实现类。改不好,可能还会引入新的bug。

    你看,接口粒度小,设计的改动也比较少。

    接口是我们设计时对外提供的契约,通过分散定义多个接口,可以预防未来变更的扩散,提供系统的灵活性和可维护性。

    不过,你可能发现,接口隔离原则跟单一职责原则有点类似。但是,还是有点区别的。

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

    单一职责原则针对的是模块、类、接口的设计,注重的是职责,这是业务逻辑上的划分。

    接口隔离原则相对于单一职责原则,一方面更侧重于接口的设计,另一方面,它的思考角度也是不同的。

    接口隔离原则提供了一种判断接口的职责是否单一的标准:通过调用者如何使用接口来间接地判定。如果调用者只使用部分接口或接口的部分功能,那么接口的设计就比较“臃肿”,违背了“接口隔离原则”。

    那可能有同学会问:“如果一个接口,按照接口隔离原则要拆,但是按照单一职责原则就不用拆,那应该怎么办呢?”

    其实很好办,根据接口隔离原则拆分时,首先必须满足单一职责原则。

    总结

    一个接口只干一件事,接口要精简单一。

    目的:高内聚、低耦合。

    好啦,每个设计原则是否运用得当,需要根据具体的业务场景,具体分析。

    参考

    极客时间专栏《设计模式之美》

    《设计模式之禅》

     

  • 相关阅读:
    Google Earth Engine APP——打印点的坐标到控制台上和map上,设置样式并更新
    1.关系数据库mysql全面总结
    【OpenCV】仿 IOS 锁屏时钟
    计算机网络之传输层------TCP协议详解
    vault安装手册
    New:WebKitX ActiveX :::Crack
    unity 摄像头拉进代码
    Web 3.0 是泡沫还是金矿?
    集卡实习总结
    15-自动化测试——理论知识
  • 原文地址:https://www.cnblogs.com/Gopher-Wei/p/15931189.html