文章目录

  • 什么是迪米特原则?
  • 迪米特法则的含义
    • 1. 只和朋友交流
      • 不遵循迪米特法则的定义
      • 遵循迪米特法则的定义
    • 2. 朋友间也是有距离的
      • 不遵循迪米特原则的设计
      • 遵循迪米特原则的设计
      • 3. 是自己的就是自己的
      • 4. 谨慎使用Serializable

什么是迪米特原则?

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

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

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

迪米特法则的含义

迪米特法则对类的低耦合提出了明确的要求,其包含以下4层含义:

1. 只和朋友交流

迪米特法则还有一个英文解释是:Only talk to your immediate friends(只与直接的朋友通信。)什么叫做直接的朋友呢?每个对象都必然会与其他对象有耦合关系,两个对象之间的 耦合就成为朋友关系,这种关系的类型有很多,例如组合、聚合、依赖等。

以老师要求体育委员清点全班女生为例:

不遵循迪米特法则的定义

5-1:老师要求清点女生类图

老师类:

public class Teacher { //老师对学生发布命令,清一下女生 public void commond(GroupLeader groupLeader){ List listGirls = new ArrayList(); //初始化女生 for(int i=0;i<20;i++){ listGirls.add(new Girl());}  //告诉体育委员开始执行清查任务groupLeader.countGirls(listGirls); }
}

体育委员类:

public class GroupLeader { //清查女生数量 public void countGirls(List<Girl> listGirls){ System.out.println("女生数量是:"+listGirls.size()); } }

女生类:

public class Girl {
}

场景类:

public class Client { public static void main(String[] args) { Teacher teacher= new Teacher(); //老师发布命令 teacher.commond(new GroupLeader()); }
}

运行结果:

女生数量是:20

体育委员按照老师的要求对女生进行了清点,并得出了数量。这个程序有什么问题,首先确定Teacher类有几个朋友类,它仅有一个朋友类—— GroupLeader。为什么Girl不是朋友类呢?Teacher也对它产生了依赖关系呀!朋友类的定义是 这样的:出现在成员变量、方法的输入输出参数中的类称为成员朋友类,而出现在方法体内部的类不属于朋友类,而Girl这个类就是出现在commond方法体内,因此不属于Teacher类的 朋友类。迪米特法则告诉我们一个类只和朋友类交流,但是刚刚定义的commond方法却 与Girl类有了交流,声明了一个List动态数组,也就是与一个陌生的类Girl有了交流, 这样就破坏了Teacher的健壮性。方法是类的一个行为,类竟然不知道自己的行为与其他类 产生依赖关系,这是不允许的,严重违反了迪米特法则。

遵循迪米特法则的定义

现在根据迪米特法则进行改造,去掉Teacher对Girl类的依赖关系。

5-2:修改后的老师要求清点女生类图

修改后的老师类:

public class Teacher { //老师对学生发布命令,清一下女生 public void commond(GroupLeader groupLeader){ //告诉体育委员开始执行清查任务 groupLeader.countGirls(); }
}

修改后的体育委员类:

public class GroupLeader { private List<Girl> listGirls; //传递全班的女生进来 public GroupLeader(List<Girl> _listGirls){ this.listGirls = _listGirls; }//清查女生数量 public void countGirls(){ System.out.println("女生数量是:"+this.listGirls.size()); } }

修改后的场景类:

public class Client { public static void main(String[] args) { //产生一个女生群体 List<Girl> listGirls = new ArrayList<Girl>(); //初始化女生 for(int i=0;i<20;i++){ listGirls.add(new Girl()); }Teacher teacher= new Teacher(); //老师发布命令 teacher.commond(new GroupLeader(listGirls)); }
}

把Teacher中对List的初始化移动到了场景类中,同时在GroupLeader中增加了对Girl的注入,避开了Teacher类对陌生类Girl的访问,降低了系统间的耦合,提高了系统的健壮性。

2. 朋友间也是有距离的

朋友类之间可以交流,但也不能无话不谈。

以安装软件为例:第一步是确认是否安装,第二步确认 License,再然后选择安装目录……这是一个典型的顺序执行动作,具体到程序中就是:调用 一个或多个类,先执行第一个方法,然后是第二个方法,根据返回结果再来看是否可以调用 第三个方法,或者第四个方法。

不遵循迪米特原则的设计

5-3:软件安装过程类图

导向类:
定义步骤方法。

public class Wizard {private Random rand = new Random(System.currentTimeMillis()); //第一步 public int first(){ System.out.println("执行第一个方法..."); return rand.nextInt(100); }//第二步 public int second(){ System.out.println("执行第二个方法..."); return rand.nextInt(100); }//第三个方法 public int third(){ System.out.println("执行第三个方法..."); return rand.nextInt(100); } }

软件安装InstallSoftware类:

public class InstallSoftware { public void installWizard(Wizard wizard){ int first = wizard.first(); //根据first返回的结果,看是否需要执行second if(first>50){ int second = wizard.second(); if(second>50){ int third = wizard.third(); if(third >50){ wizard.first(); } } } }
}

场景类:

public class Client { public static void main(String[] args) { InstallSoftware invoker = new InstallSoftware();invoker.installWizard(new Wizard()); } }

这个程序有什么问题呢?

Wizard类把太多的方法暴露给InstallSoftware类,两者的朋友关系太亲密了,耦合关系变得异 常牢固。如果要将Wizard类中的first方法返回值的类型由int改为boolean,就需要修改 InstallSoftware类,从而把修改变更的风险扩散开了。因此,这样的耦合是极度不合适的。

遵循迪米特原则的设计

5-4:重构后的软件安装过程类图

修改后的导向类:
在Wizard类中增加一个installWizard方法,对安装过程进行封装,同时把原有的三个 public方法修改为private方法。将三个步骤的访问权限修改为private,同时把InstallSoftware中的方法installWizad移动到 Wizard方法中。通过这样的重构后,Wizard类就只对外公布了一个public方法,即使要修改 first方法的返回值,影响的也仅仅只是Wizard本身,其他类不受影响,这显示了类的高内聚特性。

public class Wizard {private Random rand = new Random(System.currentTimeMillis()); //第一步 private int first(){ System.out.println("执行第一个方法..."); return rand.nextInt(100); }//第二步 private int second(){ System.out.println("执行第二个方法..."); return rand.nextInt(100); }//第三个方法private int third(){ System.out.println("执行第三个方法...");return rand.nextInt(100); }//软件安装过程 public void installWizard(){ int first = this.first(); //根据first返回的结果,看是否需要执行secondif(first>50){ int second = this.second(); if(second>50){ int third = this.third(); if(third >50){ this.first(); } } } } }

修改后的InstallSoftware类:

public class InstallSoftware { public void installWizard(Wizard wizard){ //直接调用 wizard.installWizard(); }
}

一个类公开的public属性或方法越多,修改时涉及的面也就越大,变更引起的风险扩散 也就越大。因此,为了保持朋友类间的距离,在设计时需要反复衡量:是否还可以再减少 public方法和属性,是否可以修改为private、package-private(包类型,在类、方法、变量前 不加访问权限,则默认为包类型)、protected等访问权限,是否可以加上final关键字等。

3. 是自己的就是自己的

在实际应用中经常会出现这样一个方法:放在本类中也可以,放在其他类中也没有错, 那么就应该坚持这样一个原则:如果一个方法放在本类中,既不增加类间关 系,也对本类不产生负面影响,那就放置在本类中。

4. 谨慎使用Serializable


⇐⇐ 设计模式—— 四:接口隔离原则

⇒⇒ 设计模式—— 六:开闭原则

参考:

【1】:《设计模式之禅》
【2】:面向对象设计原则之迪米特法则
【3】:《大话设计模式》
【4】:白话设计——浅谈迪米特法则

设计模式—— 五:迪米特原则相关推荐

  1. 设计模式:迪米特原则

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

  2. 设计模式解析---------迪米特原则

    迪米特原则英文名称为 Law of Demeter , 缩写是 LOD,也称最少知识原则(Least Knowledge Principle),它的原则是: 一个对象应该对其他对象有最少的了解. 也就 ...

  3. [设计模式原则]第五回:迪米特原则

    1.引言 迪米特法则(Law of Demeter)又叫作最少知识原则(LKP,Least Knowledge Principle),就是说一个对象应当对其他对象有尽可能少的了解,类与类之间的了解的越 ...

  4. 设计模式六大原则:迪米特原则-带你走进梦幻西游(四)

    转载请标明:http://blog.csdn.net/liulongling/article/details/51332685 面向对象其它六大原则 单一职责原则-带你走梦幻西游(一) 依赖倒置原则( ...

  5. java设计模式之设计原则⑤迪米特原则

    定义: (1)一个对象应该对其他对象保持最少的了解.又叫最少知道原则 (2)尽量降低类与类之间的耦合 (3)强调只和朋友交流,不和陌生人说话(意思就是对外部引入的类越少越好). 朋友:指的是出现在成员 ...

  6. 设计模式六大原则(5)——迪米特原则

    定义:一个对象应该对其他对象保持最少的了解. 问题由来:类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大. 解决方案:尽量降低类与类之间的耦合. 自从我们接触编程开始,就 ...

  7. 【学习笔记】慕课网—Java设计模式精讲 第3章 软件设计七大原则-3-6 迪米特原则(最少知道原则)...

    /** * 软件设计七大原则-迪米特原则 学习笔记 * @author cnRicky * @date 2018.11.10 */ 迪米特原则(最少知道原则) 一个对象应该对其他对象保持最少的了解.又 ...

  8. 设计模式-设计原则之迪米特原则

    例子 假设老板给项目组长下达一个任务,让其去查询课程的数量 代码 public class Course {} public class TeamLeader {public void checkNu ...

  9. 软件设计七大原则:(五)迪米特原则

    一.迪米特原则简介 定义:一个对象应该对其他对象保持最少的了解.又叫最少知道原则. 尽量降低类与类之间的耦合 优点:降低类之前的耦合 强调只和朋友交流,不和陌生人说话 什么是朋友类? 朋友类指的是出现 ...

最新文章

  1. 一文告诉你,如何使用Python构建一个“谷歌搜索”系统 | 内附代码
  2. java请求怎么获取token,如何获取变量token的值
  3. 性能测试服务器数量与线上数量不同,性能需求分析
  4. C++模板的概念<>(泛型编程)
  5. LiveVideoStackCon音视频技术大会首次来到上海
  6. 装水体积c语言,C语言基础之--sizeof()运算符的使用以及注意
  7. display:none的表单也会被提交
  8. 大量数据丢失且无法恢复!欧洲云服务巨头数据中心起火
  9. PDE2 three fundamental examples
  10. 《Excel与VBA程序设计》第四章新鲜出炉
  11. 32、剑指offer--把数组排成最小的数
  12. Fortran入门教程(五)——选择结构
  13. vue项目中使用颜色选择器
  14. 【ES6】for of用法
  15. 苏州新导_室内定位技术实现停车场下的高精度定位_室内定位技术带你找朋友
  16. LaTex学习教程——简单表格(三行线、普通表格)
  17. Java数组:一维数组的定义和赋值
  18. HTML网页中插入视频的方法
  19. ROS中的坐标系规定及数据单位
  20. mongodb 百万_关于mongodb 百万级数据 去重 查询优化的问题

热门文章

  1. 精益价值流图实践步骤
  2. slf4j中如何进行log4j配置呢?
  3. 路由器转发原理以及路由表的构成
  4. English Learning - Day59 作业打卡 2023.2.13 周一
  5. 在mac上更改文件关联
  6. Gray码问题---分治法实验2
  7. 微信恶搞很火官方提醒方法
  8. 深入比较手机网游与PC网游
  9. 远程桌面连接:出现身份验证错误,要求的函数不受支持报错,解决方法
  10. Echarts折线图获取数据库数据展示