迪米特法则来自于1987年美国东北大学(Northeastern University)一个名为“Demeter”的研究项目。迪米特法则又称为最少知识原则(LeastKnowledge Principle, LKP),其定义如下:

迪米特法则(Law of  Demeter, LoD):一个软件实体应当尽可能少地与其他实体发生相互作用。

如果一个系统符合迪米特法则,那么当其中某一个模块发生修改时,就会尽量少地影响其他模块,扩展会相对容易,这是对软件实体之间通信的限制,迪米特法则要求限制软件实体之间通信的宽度和深度。迪米特法则可降低系统的耦合度,使类与类之间保持松散的耦合关系。

迪米特法则还有几种定义形式,包括不要和“陌生人”说话只与你的直接朋友通信等,在迪米特法则中,对于一个对象,其朋友包括以下几类:

(1) 当前对象本身(this);

(2) 以参数形式传入到当前对象方法中的对象;

(3) 当前对象的成员对象;

(4) 如果当前对象的成员对象是一个集合,那么集合中的元素也都是朋友;

(5) 当前对象所创建的对象。

任何一个对象,如果满足上面的条件之一,就是当前对象的“朋友”,否则就是“陌生人”。在应用迪米特法则时,一个对象只能与直接朋友发生交互,不要与“陌生人”发生直接交互,这样做可以降低系统的耦合度,一个对象的改变不会给太多其他对象带来影响。

迪米特法则要求我们在设计系统时,应该尽量减少对象之间的交互,如果两个对象之间不必彼此直接通信,那么这两个对象就不应当发生任何直接的相互作用,如果其中的一个对象需要调用另一个对象的某一个方法的话,可以通过第三者转发这个调用。简言之,就是通过引入一个合理的第三者来降低现有对象之间的耦合度

在将迪米特法则运用到系统设计中时,要注意下面的几点:在类的划分上,应当尽量创建松耦合的类,类之间的耦合度越低,就越有利于复用,一个处在松耦合中的类一旦被修改,不会对关联的类造成太大波及在类的结构设计上,每一个类都应当尽量降低其成员变量和成员函数的访问权限在类的设计上,只要有可能,一个类型应当设计成不变类在对其他类的引用上,一个对象对其他对象的引用应当降到最低

下面通过一个简单实例来加深对迪米特法则的理解:

Sunny软件公司所开发CRM系统包含很多业务操作窗口,在这些窗口中,某些界面控件之间存在复杂的交互关系,一个控件事件的触发将导致多个其他界面控件产生响应,例如,当一个按钮(Button)被单击时,对应的列表框(List)、组合框(ComboBox)、文本框(TextBox)、文本标签(Label)等都将发生改变,在初始设计方案中,界面控件之间的交互关系可简化为如图1所示结构:

图1 初始设计方案结构图

在图1中,由于界面控件之间的交互关系复杂,导致在该窗口中增加新的界面控件时需要修改与之交互的其他控件的源代码,系统扩展性较差,也不便于增加和删除新控件。

现使用迪米特对其进行重构。

在本实例中,可以通过引入一个专门用于控制界面控件交互的中间类(Mediator)来降低界面控件之间的耦合度。引入中间类之后,界面控件之间不再发生直接引用,而是将请求先转发给中间类,再由中间类来完成对其他控件的调用。当需要增加或删除新的控件时,只需修改中间类即可,无须修改新增控件或已有控件的源代码,重构后结构如图2所示:

图2  重构后的结构图

面象对象设计原则之六:迪米特原则(LeastKnowledge Principle, LKP)的更多相关文章

  1. 面象对象设计原则之五:依赖倒置原则(The Dependency Inversion Principle,DIP)

    如果说开闭原则是面向对象设计的目标的话,那么依赖倒转原则就是面向对象设计的主要实现机制之一,它是系统抽象化的具体实现.依赖倒转原则是Robert C. Martin在1996年为“C++Reporte ...

  2. 面象对象设计原则之三:里氏替换原则(The Liskov Substitution Principle,LSP)

    里氏代换原则由2008年图灵奖得主.美国第一位计算机科学女博士Barbara Liskov教授和卡内基·梅隆大学Jeannette Wing教授于1994年提出.其严格表述如下:如果对每一个类型为S的 ...

  3. 面象对象设计原则之二:开放封闭原则(Open-Closed Principle, OCP)

    开闭原则是面向对象的可复用设计的第一块基石,它是最重要的面向对象设计原则.开闭原则由Bertrand  Meyer于1988年提出,其定义如下: 开闭原则(Open-Closed Principle, ...

  4. 面象对象设计原则之四:接口隔离原则(The Interface Segregation Principle,ISP)

    接口隔离原则定义如下: 接口隔离原则(Interface  Segregation Principle, ISP):使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口. 根 ...

  5. 面象对象设计原则之七:合成复用原则(Composition/Aggregate Reuse Principle, CARP)

    合成复用原则又称为组合/聚合复用原则(Composition/Aggregate Reuse Principle, CARP),其定义如下: 合成复用原则(Composite Reuse Princi ...

  6. 面象对象设计原则之一:单一职责原则(Single Responsibility Principle, SRP)

    单一职责原则是最简单的面向对象设计原则,它用于控制类的粒度大小.单一职责原则定义如下:单一职责原则(Single Responsibility Principle, SRP):一个类只负责一个功能领域 ...

  7. DesignPattern系列__06迪米特原则

    迪米特原则定义 迪米特原则,也叫最少知道原则,即一个类应该对自己依赖的类知道的越少越好,而你被依赖的类多么复杂,对我都没有关系.也就是说,对于别依赖的类来说,不管业务逻辑多么复杂,都应该尽量封装在类的 ...

  8. UML和模式应用5:细化阶段(9)---迈向对象设计

    1.前言 开发者如何设计对象,可以采用如下三种方式: 编码:在编码的同时进行设计 绘图然后编码:绘制一些UML,然后转到如上编码方式,在集成开发环境中编码 只绘图,不编码:使用工具从图中生成一切 本章 ...

  9. IOS设计模式的六大设计原则之迪米特法则(LOD,Law Of Demeter)

    定义 狭义的迪米特法则定义:也叫最少知识原则(LKP,Least Knowledge Principle).如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用.如果其中的一个类需要调用 ...

随机推荐

  1. Mongodb主从模式SECONDARY提升为PRIMARY

    生产环境不建议仅使用PRIMARY-SECONDARY模式 当primary挂掉,并且无法恢复时,可以把secondary提升为主节点. 注意:此时从节点可能有部分数据未同步过来,部分数据可能丢失. ...

  2. 面试被问http协议?这篇文章足够覆盖所有相关问题!

    http使用面向连接的TCP作为传输层协议.http本身无连接. 请求报文 CRLF是回车换行     方法为GET的请求报文     方法为POST的请求报文     方法 OPTIONS:这个方法 ...

  3. 启动Myeclipse报错“Failed to create the Java Virtual Machine”的解决办法

    我安装的是Myeclipse 10.7.1.装上好久没用,今天启动突然报错:Failed to create the Java Virtual Machine. 检查Myeclipse安装好使用时好的 ...

  4. intellij idea 修改背景保护色&&修改字体&&快捷键大全(转)

    文章转自http://blog.csdn.net/hpf911/article/details/16888797 近Idea比较流行,Eclipse因为maven的问题,运行起来非常慢,各种提示也不够 ...

  5. shell脚本之获取CPU使用率

    今天一个同事要测试OJ项目,同时我这边也需要知道他在压测过程中, CPU的使用率怎么样,虽说可以用top实时查看,但是进程太多了,我不需要获取那么多信息,我仅仅只要知道当前压测过程中CPU实时的使用率 ...

  6. [转]Ubuntu 常用解压与压缩命令

    .tar 文件(注:tar是打包,不是压缩!) # 仅打包,并非压缩 tar -xvf FileName.tar # 解包 tar -cvf FileName.tar DirName # 将DirNa ...

  7. 拓扑优化中SIMP方法与水平集方法有何优缺点,水平集法变换到高维,不是更复杂了

    作者:周平章链接:https://www.zhihu.com/question/52008623/answer/187927508来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注 ...

  8. AI 偏微分方程

    1.微分dx: 高阶无穷小 偏微分方程

  9. Android 动态的给Button、TextView、ImageView等控件设置了background后,再设置padding属性时该属性不起作用

    也许大家遇到这样一个问题,有时我们根据业务需要在一个ViewGroup中动态的(程序运行过程中)添加View.例如添加Button,就需要给Button添加background.padding.mar ...

  10. 包含 PHP和nginx的镜像 supervisord.conf Dockerfile 案例

    参考:https://github.com/romeOz/docker-nginx-php 1.命令: docker run --name app -d -p 8080:80 \ --net pg_n ...