2021-09-05 20:56  阅读(117)
文章分类:设计原则 文章标签:设计原则
©  原文作者:Demo_Null 原文地址:https://cloud.tencent.com/developer/user/1751610

1.1 概述

  迪米特法则(Law of Demeter,LoD)又叫作最少知识原则(Least Knowledge Principle,LKP),产生于 1987 年美国东北大学的一个名为迪米特的研究项目,由伊恩·荷兰提出,被 UML 创始者之一的布奇普及,后来又因为在经典著作《程序员修炼之道》提及而广为人知。迪米特法则的定义是:只与你的直接朋友交谈,不跟 “陌生人” 说话(Talk only to your immediate friends and not to strangers)。其含义是:如果两个软件实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该调用。其目的是降低类之间的耦合度,提高模块的相对独立性。   迪米特法则中的 “朋友” 是指:当前对象本身、当前对象的成员对象、当前对象所创建的对象、当前对象的方法参数等,这些对象同当前对象存在关联、聚合或组合关系,可以直接访问这些对象的方法。需要注意的是,过度使用迪米特法则会使系统产生大量的中介类,从而增加系统的复杂性,使模块之间的通信效率降低。所以,在釆用迪米特法则时需要反复权衡,确保高内聚和低耦合的同时,保证系统的结构清晰。

1.2 优点

 ① 降低了类之间的耦合度,提高了模块的相对独立性。  ② 由于亲合度降低,从而提高了类的可复用率和系统的扩展性。

1.3 案例

  学过 java 的应该都能看懂下面的代码,Client 通过 Data 的 getPersonList 方法获取了人员集合,然后将其遍历,这样写有没有问题呢?只看结果是没有问题的,但是它不符合迪米特法则。迪米特法则要求只跟朋友说话,其朋友指的是当前对象本身、当前对象的成员对象、当前对象所创建的对象、当前对象的方法参数等。而 getPersonList 返回的集合中的 Person 并不是 Client 的朋友。

    /**
     * @author Demo_Null
     * @version 1.0
     * @date 2020/12/16 19:11
     */
    public class Data {
    
        public List<Person> getPersonList() {
            return new ArrayList<Person>() {{
                this.add(new Person("张三", 23));
                this.add(new Person("李四", 24));
                this.add(new Person("王五", 25));
            }};
        }
    }
    /**
     * @author Demo_Null
     * @version 1.0
     * @date 2020/12/16 19:17
     */
    public class Client {
    
        public static void main(String[] args) {
            Data data = new Data();
            List<Person> personList = data.getPersonList();
            for (Person person : personList) {
                System.out.println(person);
            }
        }
    }

  我们想要的只是遍历人员,为什么要先把人员集合取出来自己去遍历呢?我们去指使 Data 类帮我们遍历不香么。于使我们将代码改为了如下形式,由创建人员集合的类去完成遍历操作,我们调用其暴露出来的遍历方法即可。是自己的就是自己的,在项目中有一些方法,放在本类中也可以,放在其他类中也没有错误。我们可以坚持这样一个原则:如果一个方法放在本类中,即不增加类间关系,也对本类不产生负面影响,就放置在本类中。

    /**
     * @author Demo_Null
     * @version 1.0
     * @date 2020/12/16 19:50
     */
    public class Data {
    
        public List<Person> getPersonList() {
            return new ArrayList<Person>() {{
                this.add(new Person("张三", 23));
                this.add(new Person("李四", 24));
                this.add(new Person("王五", 25));
            }};
        }
    
        public void forList() {
            List<Person> personList = this.getPersonList();
            for (Person person : personList) {
                System.out.println(person);
            }
        }
    }
    /**
     * @author Demo_Null
     * @version 1.0
     * @date 2020/12/16 19:50
     */
    public class Client {
    
        public static void main(String[] args) {
            Data data = new Data();
            data.forList();
        }
    }

  迪米特法则的核心观念就是类间解耦,弱耦合,只有弱耦合了以后,类的复用率才可以提高,其要求的结果就是产生了大量的中转或跳转类,类只能和朋友交流,朋友少了你业务跑不起来,朋友多了,你项目管理就复杂,这个就需要自己考量了。迪米特法则要求我们类间解耦,但是解耦是有限度的,除非是计算机的最小符号二进制的 0 和 1,那才是完全解耦,我们在实际的项目中时,需要适度的考虑这个法则,别为了套用法则而做项目,法则只是一个参考,违背了法则,也不会有人判你刑,项目也未必会失败。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

点赞(1)
版权归原创作者所有,任何形式转载请联系作者; Java 技术驿站 >> 七大设计原则之迪米特法则
上一篇
七大设计原则之开闭原则
下一篇
七大设计原则之合成复用原则