什么是迪米特法则(Law of Demeter, LoD)

 迪米特法则也可以称为最少知识法则(Least Knowledge Principle, LKP)。它们都描述了一个规则:一个对象应该对其他对象有最少的了解。通俗来说,一个类应该对自己需要耦合或调用的类知道最少,也就是对于被依赖的类,向外公开的方法应该尽可能的少。

 迪米特法则还有一种解释:Only talk to your immediate friends,只与直接朋友进行通信。关于朋友给出如下解释:两个对象之间的耦合关系称之为朋友,通常有依赖,关联,聚合,组成等。而直接朋友通常表现为关联,聚合和组成关系,即两个对象之间联系更为紧密,通常以成员变量,方法参数和返回值的形式出现。

LoD实例演示

 迪米特法则强调了下面两点:

  • 从被依赖者的角度:只暴露应该暴露的方法或属性,即编写相关的类时确定方法和属性的权限
  • 从依赖者的角度来看,只依赖应该依赖的对象

先举例演示第一点:当我们按下计算机的按钮的时候,计算机会指行一系列操作:保存当前任务,关闭相关服务,接着关闭显示屏,最后关闭电源,这些操作完成则计算机才算关闭。如下是代码示例:

//计算机类
public class Computer{public void saveCurrentTask(){//do something}public void closeService(){//do something}public void closeScreen(){//do something}public void closePower(){//do something}public void close(){saveCurrentTask();closeService();closeScreen();closePower();}
}//人
public class Person{private Computer c;...public void clickCloseButton(){//现在你要开始关闭计算机了,正常来说你只需要调用close()方法即可,//但是你发现Computer所有的方法都是公开的,该怎么关闭呢?于是你写下了以下关闭的流程:        c.saveCurrentTask();c.closePower();c.close();//亦或是以下的操作        c.closePower();//还可能是以下的操作c.close();c.closePower();}}

 观察上面的代码我们发现了什么问题:对于人来说,我期待的结果只是按下关闭电钮然后计算机“啪”的给我关了,而不是需要我去小心的去保存当前正在执行的任务等等。在上面的代码中,c是一个完全暴露的对象,它的方法是完全公开的,对于Person来说,手里面就如同多出了好几把钥匙,至于具体用哪一把他不知道,所以只能一把一把的去试一遍,显然这样的设计是不对的。

 根据迪米特法则的第一点:从被依赖者的角度,只暴露应该暴露的方法。在本例中,应该暴露的方法就是close(),关于计算机的其他操作不是依赖者应该关注的问题,应该对依赖者关闭,重新设计如下:

//计算机类
public class Computer{private void saveCurrentTask(){//do something}private void closeService(){//do something}private void closeScreen(){//do something}private void closePower(){//do something}public void close(){saveCurrentTask();closeService();closeScreen();closePower();}
}//人
public class Person{private Computer c;...public  void clickCloseButton(){c.close();}}

现在举例演示第二点:在我们生活中会有这样的情况,比如张三去找李四帮忙做一件事,对于李四来说这件事也很棘手,李四也做不了,但是李四有一个好哥们王五却能完成这件事,所以李四就把这件事交给王五去办(在本例中,张三和王五是不认识的)。现在我们暂定张三为A,李四为B,王五为C,代码示例如下:

//张三找李四办事
public class A {public String name;public A(String name) {this.name = name;}public B getB(String name) {return new B(name);}public void work() {B b = getB("李四");C c = b.getC("王五");c.work();}
}//李四办不了于是去找王五
public class B {private String name;public B(String name) {this.name = name;}public C getC(String name) {return new C(name);}
}//对于王五来说so easy,办得妥妥的
public class C {public String name;public C(String name) {this.name = name;}public void work() {System.out.println(name + "把这件事做好了");}
}public class Client {public static void main(String[] args) {A a = new A("张三");a.work();}
}
结果:王五把事情做好了

 上面的设计输出答案是正确的,王五确实把事情办妥了。但是我们仔细看业务逻辑确发现这样做事不对的。张三和王五互相不认识,那为什么代表张三的A类中会有代表李四的C类呢?这样明显是违背了迪米特法则的。现在我们对上面的代码进行重构,根据迪米特法则的第二点:从依赖者的角度来看,只依赖应该依赖的对象。在本例中,张三只认识李四,那么只能依赖李四。重构后代码如下:

//张三认识李四,只依赖李四
public class A {public String name;public A(String name) {this.name = name;}public B getB(String name) {return new B(name);}public void work() {B b = getB("李四");b.work();}
}//李四依赖王五
public class B {private String name;public B(String name) {this.name = name;}public C getC(String name) {return new C(name);}public void work(){C c = getC("王五");c.work();}
}//王五把事情办得妥妥的
public class C {public String name;public C(String name) {this.name = name;}public void work() {System.out.println(name + "把这件事做好了");}
}public class Client {public static void main(String[] args) {A a = new A("张三");a.work();}
}
结果:王五把事情做好了

总结

 迪米特法则的目的是让类之间解耦,降低耦合度,提高类的复用性。但是设计原则并非有利无弊,使用迪米特法则会产生大量的中转类或跳转类,导致系统复杂度提高。在实际的项目中,需要适度的考虑这个原则,不能因为套用原则而反而使项目设计变得复杂。

参考书籍与链接

  • 《设计模式之禅》
  • https://tianweili.github.io/2015/02/12/设计模式六大原则-迪米特法则/
  • https://blog.csdn.net/zhengzhb/article/details/7296930
  • https://www.jianshu.com/p/30931aab5ea0

面向对象六大原则——迪米特法则相关推荐

  1. 设计模式六大原则——迪米特法则(LoD)

    1.背景 在图书馆借书.刚開始的时候,直接跑到对应的楼层去,到里面去转,去找要借的书,在里面溜达半天才干找到:后来知道图书馆有一个电脑查询处.然后直接在电脑上输入想要借的书,电脑就会显示你想要借的书的 ...

  2. 面向对象设计模式原则-迪米特法则

    迪米特法则(LOD,Law of Demeter) 注:迪米特法则又名 :最少知识原则 定义:一个软件实体应当尽可能少地与其他实体发生相互作用. 一个对象应当对其他对象尽可能少的了解,从而降低各个对象 ...

  3. java 迪米特_Java设计原则—迪米特法则(转)

    定义: 迪米特法则(Law of Demeter,LoD)也称为最少知识原则(Least Knowledge Principle,LKP). 一个对象应该对其他对象有最少的了解.通俗地讲,一个类应该对 ...

  4. 面向对象六大原则详解

    本文来说下面向对象六大原则 文章目录 概述 单一职责原则 里氏替换原则 依赖倒置原则 接口隔离原则 迪米特法则 开闭原则 六大原则总结 概述 这是设计模式系列开篇的第一篇文章.也是我学习设计模式过程中 ...

  5. 【设计模式】第一章 面向对象六大原则

    第一章 面向对象六大原则 文章目录 第一章 面向对象六大原则 一.指导思想 二.面向对象六大原则 1.单一职责原则 2.开闭原则 3.里氏替换原则 4.依赖倒置原则 5.接口隔离原则 6.迪米特法则 ...

  6. Java基础学习总结(84)——Java面向对象六大原则和设计模式

    面向对象六大原则 在此之前,有一点需要大家知道,熟悉这些原则并不是说你写出的程序就一定灵活.清晰,只是为你优秀的代码之路铺上了一层栅栏,在这些原则的指导下,你才能避免陷入一些常见的代码泥沼,从而让你写 ...

  7. java 面向对象原则_Java基础:面向对象六大原则

    本文主要介绍了面向对象六大原则. 单一职责原则(Single-Resposibility Principle). "对一个类而言,应该仅有一个引起它变化的原因."本原则是我们非常熟 ...

  8. 六大设计模式原则-迪米特法则

    一.迪米特法则定义 迪米特法则又最少知识原则,其定义如下: 迪米特法则(Law of Demeter, LoD):一个软件实体应当尽可能少的与其他实体发生相互作用. 二.迪米特法则描述 如果一个系统满 ...

  9. 六大设计原则 ——迪米特法则

    迪米特法则描述的是:一个对象应该对其他对象有最少的了解.通俗的讲 ,一个类应该对自己需要耦合或调用的类知道得最少,你的内部是如何复杂都和我没关系,那是你的事,我就知道你提供了这么多public方法,我 ...

最新文章

  1. python异常处理--try except else raise finally
  2. Jmeter之Beanshell使用(二)Java处理JSON块
  3. adb打开网页_adb命令打开手机设置页面
  4. Ember入门指南——教程目录
  5. 利用 keyCode 控制数字输入框
  6. redis 原码安装
  7. linux shell 脚本 supress,Linux指令和shell脚本
  8. java文件复制速度_【Java】Java代码拷贝文件的速度
  9. Apache Avro 与 Thrift 比较
  10. 如何使用scikit-learn工具来进行PCA降维
  11. Opencv项目实战:05 物体检测
  12. 成都职称计算机 报几科,成都2018年7月上职称计算机考试报名事项通知
  13. JAVA学习笔记_小写数字转换成大写且带单位_金额小写转大写
  14. FineReport 11.0 帆软报表 授权文件 补丁
  15. readability: 英文文本数据可读性库
  16. JVM-04-运行时数据区-堆,方法区
  17. ARM7-LPC213x(二)LED流水灯
  18. 软件工程——编码、测试、维护
  19. 创业公司股权分配的七大实操建议
  20. uniApp开发小程序(7)使用mescroll配置上啦下拉的样式,以及分类页面的配置

热门文章

  1. 建立一个最简单的FLV和MP4播放器
  2. Python七天作业
  3. 3.3 SRAM和DRAM
  4. SRAM和DRAM以及ROM的区别
  5. 这3款音频转文字软件,让你轻松整理各种音频内容
  6. pythonturtle库使用心得_[python库]turtle库总结
  7. python123自定义幂函数_Python内置函数
  8. Spring for Kafka版本对照
  9. Selenium—iframe的操作
  10. Mac:查看端口占用