面向对象六大原则——迪米特法则
什么是迪米特法则(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
面向对象六大原则——迪米特法则相关推荐
- 设计模式六大原则——迪米特法则(LoD)
1.背景 在图书馆借书.刚開始的时候,直接跑到对应的楼层去,到里面去转,去找要借的书,在里面溜达半天才干找到:后来知道图书馆有一个电脑查询处.然后直接在电脑上输入想要借的书,电脑就会显示你想要借的书的 ...
- 面向对象设计模式原则-迪米特法则
迪米特法则(LOD,Law of Demeter) 注:迪米特法则又名 :最少知识原则 定义:一个软件实体应当尽可能少地与其他实体发生相互作用. 一个对象应当对其他对象尽可能少的了解,从而降低各个对象 ...
- java 迪米特_Java设计原则—迪米特法则(转)
定义: 迪米特法则(Law of Demeter,LoD)也称为最少知识原则(Least Knowledge Principle,LKP). 一个对象应该对其他对象有最少的了解.通俗地讲,一个类应该对 ...
- 面向对象六大原则详解
本文来说下面向对象六大原则 文章目录 概述 单一职责原则 里氏替换原则 依赖倒置原则 接口隔离原则 迪米特法则 开闭原则 六大原则总结 概述 这是设计模式系列开篇的第一篇文章.也是我学习设计模式过程中 ...
- 【设计模式】第一章 面向对象六大原则
第一章 面向对象六大原则 文章目录 第一章 面向对象六大原则 一.指导思想 二.面向对象六大原则 1.单一职责原则 2.开闭原则 3.里氏替换原则 4.依赖倒置原则 5.接口隔离原则 6.迪米特法则 ...
- Java基础学习总结(84)——Java面向对象六大原则和设计模式
面向对象六大原则 在此之前,有一点需要大家知道,熟悉这些原则并不是说你写出的程序就一定灵活.清晰,只是为你优秀的代码之路铺上了一层栅栏,在这些原则的指导下,你才能避免陷入一些常见的代码泥沼,从而让你写 ...
- java 面向对象原则_Java基础:面向对象六大原则
本文主要介绍了面向对象六大原则. 单一职责原则(Single-Resposibility Principle). "对一个类而言,应该仅有一个引起它变化的原因."本原则是我们非常熟 ...
- 六大设计模式原则-迪米特法则
一.迪米特法则定义 迪米特法则又最少知识原则,其定义如下: 迪米特法则(Law of Demeter, LoD):一个软件实体应当尽可能少的与其他实体发生相互作用. 二.迪米特法则描述 如果一个系统满 ...
- 六大设计原则 ——迪米特法则
迪米特法则描述的是:一个对象应该对其他对象有最少的了解.通俗的讲 ,一个类应该对自己需要耦合或调用的类知道得最少,你的内部是如何复杂都和我没关系,那是你的事,我就知道你提供了这么多public方法,我 ...
最新文章
- python异常处理--try except else raise finally
- Jmeter之Beanshell使用(二)Java处理JSON块
- adb打开网页_adb命令打开手机设置页面
- Ember入门指南——教程目录
- 利用 keyCode 控制数字输入框
- redis 原码安装
- linux shell 脚本 supress,Linux指令和shell脚本
- java文件复制速度_【Java】Java代码拷贝文件的速度
- Apache Avro 与 Thrift 比较
- 如何使用scikit-learn工具来进行PCA降维
- Opencv项目实战:05 物体检测
- 成都职称计算机 报几科,成都2018年7月上职称计算机考试报名事项通知
- JAVA学习笔记_小写数字转换成大写且带单位_金额小写转大写
- FineReport 11.0 帆软报表 授权文件 补丁
- readability: 英文文本数据可读性库
- JVM-04-运行时数据区-堆,方法区
- ARM7-LPC213x(二)LED流水灯
- 软件工程——编码、测试、维护
- 创业公司股权分配的七大实操建议
- uniApp开发小程序(7)使用mescroll配置上啦下拉的样式,以及分类页面的配置