• 设计原则之【迪米特法则】


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

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

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

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

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

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

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

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

    LOD迪米特法则

    实习生表妹第一天去公司...

    我:妹啊,第一天去公司感觉怎么样呢?

    表妹:感觉同事们有些冷淡😔

    我:咋啦?

    表妹:我在办理入职的时候,和我对接的张同事突然有事走开了,我当时看另一位同事在聊微信,就麻烦他帮我办理,但是他却让我等张同事回来。

    我:原来是这样子,首先,他不是你的直接对接人呀,其次,说不定他自己也有事情在处理呢。

    这不很像我们软件开发中的“迪米特法则”嘛?


    每个模块只应该了解那些与它关系密切的模块的有限知识。或者说,每个模块只和自己的朋友“说话”,不和陌生人“说话”。也叫“最少知识原则”。

    从上面的描述中,我们可以看出,迪米特法则包含前后两个部分,如果我们把一个模块看作是一个人,那么要实现“一个人应该对其他人有最少的了解”,应该做到这两点:

    1、只和直接的朋友交流;

    2、减少对朋友的了解。

    接下来就详细说说如何做到这两点。

    首先,我们来看一下,什么叫“朋友”?

    软件开发中的朋友:两个对象之间的耦合关系称之为“朋友”,通常有依赖、关联、聚合和组合等。而直接朋友则通常表现为关联、聚合和组合关系,即两个对象之间联系更为紧密,通常以成员变量,方法的参数和返回值的形式出现。

    减少对朋友的了解

    一个类公开的public属性或方法越多,修改时涉及的面也就越大,变更引起的风险扩散就越大。

    就如同前面的场景,表妹只知道自己的直接对接人是负责给新员工办理入职手续的,但是具体的操作,表妹是不知道的。

    我们来看一下明星和粉丝互动的场景:

    复制代码
     1 // 粉丝类
     2 public class Fans {
     3  4     public void shakeHands(){
     5         System.out.println("与偶像握手");
     6     }
     7     public void sign(){
     8         System.out.println("偶像给我签名");
     9     }
    10     public void groupPhoto(){
    11         System.out.println("与偶像合影");
    12     }
    13     
    14     public void interaction(){
    15         shakeHands();
    16         sign();
    17         groupPhoto();
    18     }
    19 }
    20 21 // 偶像类
    22 public class Star{
    23     private Fans f;
    24     
    25     ...
    26     
    27     public void interactWithFans(){
    28       // 现在偶像要和粉丝互动,正常来说,她只需要调用interaction()方法即可,
    29       // 但是,她发现Fans所有的方法都是公开的,该如何互动呢?可能:
    30         f.shakeHands();
    31         f.sign();
    32         f.groupPhoto();
    33         
    34         // 亦或是以下的操作 
    35         f.sign();
    36         f.groupPhoto();
    37         
    38         // 还可能是以下的操作
    39         f.interaction();
    40     }
    41 }
    复制代码

    你看,粉丝作为明星的朋友,公开了很多种互动方式,使得明星对粉丝的了解过多,这样明星得花很大精力去考虑以哪种方式和粉丝互动。那么,这里的f对象应该暴露哪些方法呢?很显然,对于明星Star来说,只需关注和粉丝的互动操作,而不关心具体是如何互动的,因此,只需要暴露interaction()方法。

    那么,上述的代码应该修改为:

    复制代码
     1 // 粉丝类
     2 public class Fans {
     3  4     private void shakeHands(){
     5         System.out.println("与偶像握手");
     6     }
     7     private void sign(){
     8         System.out.println("偶像给我签名");
     9     }
    10     private void groupPhoto(){
    11         System.out.println("与偶像合影");
    12     }
    13     
    14     public void interaction(){
    15         shakeHands();
    16         sign();
    17         groupPhoto();
    18     }
    19 }
    20 21 // 偶像类
    22 public class Star{
    23     private Fans f;
    24     
    25     ...
    26     
    27     public void interactWithFans(){
    28         // 这时候,偶像她只管与粉丝互动就可以了,不管具体是握手、签名还是合影。
    29         f.interaction();
    30     }
    31 }
    复制代码

    你看,这时明星和粉丝的互动就简单多了。

    通俗地讲,一个类应该对自己需要耦合或调用的类知道得最少,我就知道你提供的这么多public方法,我就调用这么多,其他的我一概不关心。

    其实,明星由于全身心投入艺术,所以许多日常事务由经济人负责处理,如粉丝见面会,和媒体公司的业务洽谈等。这里的经纪人就是明星的直接朋友,粉丝和媒体公司是明星的间接朋友。

    只和直接的朋友交流

    现在,我们在刚才的场景中,加多一个经纪人类:

    复制代码
     1 // 粉丝类
     2 public class Fans {
     3  4     private void shakeHands(){
     5         System.out.println("与偶像握手");
     6     }
     7     private void sign(){
     8         System.out.println("偶像给我签名");
     9     }
    10     private void groupPhoto(){
    11         System.out.println("与偶像合影");
    12     }
    13     
    14     public void interaction(){
    15         shakeHands();
    16         sign();
    17         groupPhoto();
    18     }
    19 }
    20 21 // 经纪人类
    22 public class Broker {
    23     private Fans f;       // 负责粉丝见面会
    24     private Company c;    // 负责商务洽谈
    25     ...
    26     
    27     // 开粉丝互动会
    28     public void openInteraction() {
    29         f.interaction();
    30     }
    31 }
    32 33 // 偶像类
    34 public class Star{
    35     // 明星的经纪人
    36     private Broker b;
    37     
    38     ...
    39     
    40     // 粉丝互动会,由经纪人打理
    41     public void interactWithFans(){
    42         b.openInteraction();
    43     }
    44 }
    复制代码

    你看,明星的直接朋友只有一个,也就是他的经纪人,无需了解粉丝和公司。这样做有一个好处,就是能够简化对象与对象之间的通信,进而减轻依赖,提供更高的灵活性,当然也可以提供一定的安全性。

    总结

    不该有直接依赖关系的类之间,不要有依赖;

    有依赖关系的类之间,尽量只依赖必要的接口(也就是定义中的“有限知识”)。

    好啦,不要为了应用设计原则而应用设计原则,我们在应用设计原则的时候,一定要具体问题具体分析。

    参考

    《大话设计模式》

    《设计模式之禅》

    https://www.jianshu.com/p/14589fb6978e

    https://www.itheima.com/news/20210819/173818.html

  • 相关阅读:
    JAVAWeb1:登录页面
    小国王——状压DP
    TCP协议
    AI算法,又整新活!萌妹子来挑战~
    Sovit3D数字孪生平台 助力智慧海上风电场项目加速
    嵌入式养成计划-35------C++绪论------C++数据类型------array容器------命名空间
    大数据之kafka应用
    传统Tier1「杀红眼」!Mobileye阵营寻求「强化」感知能力
    C++异常处理和断言
    网络基本概念
  • 原文地址:https://www.cnblogs.com/Gopher-Wei/p/15949567.html