软件设计原则-迪米特原则讲解以及代码示例

简介: 迪米特原则(Law of Demeter,简称LoD)也被称为最少知识原则(Least Knowledge Principle,LKP),是面向对象设计的一种重要原则。迪米特原则的核心思想是尽量减少对象之间的交互,使得系统中的模块能够相对独立地变化。

 迪米特原则

一,介绍

1.前言

迪米特原则(Law of Demeter,简称LoD)也被称为最少知识原则(Least Knowledge Principle,LKP),是面向对象设计的一种重要原则。迪米特原则的核心思想是尽量减少对象之间的交互,使得系统中的模块能够相对独立地变化。

迪米特原则最初是由Ian Holland和Richard Gabriel在1987年的OOPSLA(Object-Oriented Programming, Systems, Languages & Applications)会议上提出的,并由C. J. Date和Barbara Liskov进一步发展完善。迪米特原则被广泛应用于软件设计、系统架构等领域,并成为面向对象设计中的一个重要原则之一。

迪米特原则的核心思想可以用“不要和陌生人说话”来形象地概括。也就是说,一个对象应该尽可能地减少与其他对象之间的直接交互,只与它所认识的朋友类进行交互。朋友类包括两种:一种是当前对象本身,另一种是当前对象所持有的对象(成员变量)、方法参数中传入的对象、或内部创建的对象等。

迪米特原则的优点在于:

- 降低类之间的耦合度,使得系统更加灵活,易于维护和扩展。

- 促进类的复用,提高代码的重用性和可读性。

- 提高系统的稳定性和安全性,减少由于类之间直接交互而带来的风险。

迪米特原则的实现主要有以下几种方式:

1. 只与朋友类交互。即一个类只与自己的成员、参数、返回值中所涉及到的类进行交互,而不直接与其他类进行交互。

2. 封装类的内部细节。即一个类不应该暴露其内部的实现细节,只提供必要的接口进行交互。

3. 引入第三方代理。即通过引入一个中间类来封装和隔离两个不同的类之间的交互。

2.何时使用米莱迪原则

    1. 当一个类或模块承担了过多的功能或任务,导致其代码的可读性、可维护性和可测试性降低时,我们可以使用米莱迪原则来拆分这个类或模块,使其承担更加明确的单一责任。
    2. 当我们需要修改一个类或模块时,如果这个类或模块承担了多种不相关的责任,那么修改的影响范围可能会很大,也容易引入错误。在这种情况下,使用米莱迪原则将这个类或模块拆分成多个承担单一责任的小模块,可以降低修改的风险和成本。
    3. 当我们需要进行代码重构时,根据米莱迪原则对代码进行重组和重构,可以使代码更加清晰、易于理解和维护。同时,这也可以避免模块之间的耦合和依赖过度,提高系统的可扩展性和灵活性。

    二,代码示例

    下面以一个简单的例子来说明迪米特原则:

    public class Person {
        private String name;
        private List<Friend> friends;
        public Person(String name, List<Friend> friends) {
            this.name = name;
            this.friends = friends;
        }
        public void sendGifts(Friend friend) {
            System.out.println(name + " is sending gifts to " + friend.getName());
        }
        public void sendGiftsToAll() {
            for (Friend friend : friends) {
                sendGifts(friend);
            }
        }
    }
    public class Friend {
        private String name;
        public Friend(String name) {
            this.name = name;
        }
        public String getName() {
            return name;
        }
    }

    image.gif

     

    在这个例子中,`Person`类尝试给自己的好友们送礼物。`Person`类持有一个`List`类型的`friends`成员变量,表示它的朋友列表。在`sendGiftsToAll`方法中,`Person`类遍历它的所有好友,并调用`sendGifts`方法给每个好友送礼物。

    然而,这个设计违反了迪米特原则。`Person`类直接操作`Friend`对象,即它和陌生的`Friend`类直接进行交互。这样做的问题在于`Person`类对`Friend`类的依赖过于紧密,增加了系统的耦合性。如果系统需要修改`Friend`类或者更换成其他类型的好友,那么就会导致`Person`类的修改,从而影响整个系统的稳定性和安全性。

    为了符合迪米特原则,我们可以通过引入中间类来隔离`Person`类和`Friend`类之间的交互。具体做法是在`Person`类中引入`GiftSender`类,让`GiftSender`类来负责处理礼物的送出:

    public class Person {
        private String name;
        private List<Friend> friends;
        public Person(String name, List<Friend> friends) {
            this.name = name;
            this.friends = friends;
        }
        public void sendGiftsToAll(GiftSender giftSender) {
            for (Friend friend : friends) {
                giftSender.sendGifts(name, friend);
            }
        }
    }
    public class GiftSender {
        public void sendGifts(String senderName, Friend friend) {
            System.out.println(senderName + " is sending gifts to " + friend.getName());
        }
    }

    image.gif

     

    在这个设计中,`Person`类不再直接操作`Friend`对象,而是通过`GiftSender`类来进行交互。`GiftSender`类只对外公开一个方法`sendGifts`,它是`Person`类的朋友类,负责处理礼物的送出。这样做的好处在于,如果系统需要更换成其他类型或者更改礼物送出的方式,只需要修改`GiftSender`类即可,`Person`类无需做出任何修改,从而减少了系统维护的成本。

    总之,迪米特原则要求我们尽量减少对象之间的交互,使得系统中的模块能够相对独立地变化。通过遵循迪米特原则,我们可以降低类之间的耦合度,提高系统的灵活性、扩展性和可维护性,从而实现更加优秀的软件设计。

    三,优缺点

    迪米特原则(Law of Demeter,LoD),也被称为最少知识原则(Principle of Least Knowledge),是面向对象设计的一个原则,它强调一个对象应该尽量减少与其他对象之间的交互,只与直接的朋友进行通信。迪米特原则具有以下优点和缺点:

    优点:

    1. 降低耦合度:迪米特原则要求一个对象只与其直接的朋友发生交互,而不需要了解其他对象的内部细节。这降低了对象之间的耦合度,使得系统更加灵活、可扩展和易于维护。

    2. 提高模块的独立性:根据迪米特原则,对象只与其直接的朋友进行通信,而不需要与其他对象产生联系。这使得每个模块具有较高的独立性,可以更容易地被理解、修改和重用。

    3. 增强了系统的可测试性:由于对象之间的耦合度降低,模块间的依赖减少,提高了系统的可测试性。我们可以更容易地对单个模块进行测试,而不需要关注其依赖的其他模块。

    4. 减少了代码的脆弱性:当一个对象只与其直接的朋友进行通信时,即使其他对象发生变化,也不会对该对象产生直接的影响。这减少了代码的脆弱性,使得系统更加健壮和稳定。

    缺点:

    1. 增加了消息传递的复杂性:迪米特原则要求对象只与其直接的朋友进行通信,这可能增加了消息传递的复杂性。需要引入额外的中间对象作为消息的传递者,导致系统的结构变得复杂。

    2. 可能导致过多的中间对象:为了减少对象之间的直接交互,可能会引入过多的中间对象。这增加了系统的复杂性和维护成本,也会影响系统的性能。

    3. 可能破坏封装性:迪米特原则强调对象只与其直接的朋友进行通信,这可能会泄露一些内部的实现细节,破坏了对象的封装性。

    总结起来,迪米特原则通过降低对象之间的耦合度、提高模块的独立性和可测试性来改善软件系统的设计质量。然而,它也可能增加消息传递的复杂性、引入过多的中间对象,并破坏封装性。因此,在应用迪米特原则时需要权衡利弊,根据具体的设计需求和实际情况选择适合的设计方案。

    目录
    相关文章
    |
    测试技术
    软件设计原则-里氏替换原则讲解以及代码示例
    里氏替换原则(Liskov Substitution Principle,LSP)是面向对象设计中的一条重要原则,它由Barbara Liskov在1987年提出。 里氏替换原则的核心思想是:父类的对象可以被子类的对象替换,而程序的行为不会发生变化。也就是说,如果一个类型A是另一个类型B的子类型,那么在任何使用B的地方都可以使用A,而不会引起错误或异常。
    575 0
    软件设计原则-接口隔离原则讲解以及代码示例
    接口隔离原则(Interface Segregation Principle,ISP)是面向对象设计中的一个原则,提倡使用多个专门的接口,而不使用单一的大接口。它最早由Robert C. Martin在其《敏捷软件开发:原则、模式与实践》一书中提出。 接口隔离原则的核心思想是:客户端不应该依赖于它不需要的接口。也就是说,一个类或模块不应该强迫它的用户去依赖无用的接口。相反,应该将大接口拆分成多个小接口,符合客户端的需求,使客户端只依赖于它真正需要的接口。 接口隔离原则的目标是降低类或模块之间的耦合度,提高代码的可维护性、可扩展性和可测试性。通过使用多个专门的接口,我们可以避免类或模块之间出现不
    145 0
    |
    测试技术 数据库
    软件设计原则-依赖倒置原则讲解以及代码示例
    依赖倒置原则(Dependency Inversion Principle,DIP)是面向对象设计中的一个重要原则,由Robert C. Martin提出。 依赖倒置原则的核心思想是:高层模块不应该依赖于低层模块,二者都应该依赖于抽象。抽象不应该依赖于具体实现细节,而具体实现细节应该依赖于抽象。这意味着我们在进行系统设计时,应该尽量使用抽象类或接口来定义对象之间的依赖关系,而不是直接依赖于具体的实现类
    474 0
    |
    设计模式 Java 关系型数据库
    软件设计原则-开闭原则讲解以及代码示例
    开闭原则(Open-Closed Principle,OCP)是面向对象设计中的一条重要原则,它由Bertrand Meyer在其著作《面向对象软件构造》中提出,并成为SOLID原则之一。 开闭原则的核心思想是:软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。简单来说,就是在不修改已有代码的情况下,通过扩展来实现新的功能或变化。
    483 0
    六大设计原则-迪米特原则【Low Of Demeter】
    六大设计原则-迪米特原则【Low Of Demeter】
    45 0
    |
    存储 关系型数据库
    软件设计原则SOLID+组合聚合+迪米特原则(附代码讲解)
    软件设计原则SOLID+组合聚合+迪米特原则(附代码讲解)
    82 0
    |
    程序员 测试技术
    面向对象设计五个基本原则
    只有聪明人才能看见的简介~( ̄▽ ̄~)~
    105 0
    软件架构设计原则--迪米特原则
    本专栏内容参考自:咕泡学院Tom老师的《Spring5核心原理与30个类手写实战》,仅作个人学习记录使用,如有侵权,联系速删
    软件架构设计原则--迪米特原则
    |
    设计模式
    迪米特原则|设计原则
    本文是讲述 六大设计原则 的最后一篇,为大家讲述 迪米特原则
    |
    设计模式
    设计模式七大原则——迪米特原则
    设计模式七大原则——迪米特原则
    设计模式七大原则——迪米特原则