标准定义
迪米特法则 (Law of Demeter, LoD) 的定义如下:
每个单元只能和它的朋友交谈: 不能和陌生单元交谈
生活案例
福尔摩斯是有名的侦探, 所有的事情通过他的演绎法都原形毕露. 在福尔摩斯探案集的第一篇血字的研究, 这是华生和福尔摩斯第一次相遇, 华生对他的探案方式匪夷所思, 不理解其中的道理, 但是到最后, 福尔摩斯把案件破解之后, 华生才恍然大悟, 原来还能这么玩. 由发现疑点到破解案件找出凶手的过程中, 福尔摩斯并没有过多地透露自己的破案细节, 断案过程, 而是保持一个他人看不透的状态. 这样的一种侦探方式, 一方面能够让福尔摩斯仔细思考各种线索的联系, 找出判案的依据, 而不是频繁地被打断, 同时打断了思路. 另外一个方面也是为了保证探案过程的私密性, 防止因为泄露等原因, 让逃犯知晓并及时逃走.
神探夏洛克
迪米特法则就是福尔摩斯的探案过程, 不能过多的透露想法. 保持神秘感, 一方面有利于自己类的管理, 另外一个方面, 是为了防止别人调用自己某些类的时候破坏了程序, 造成不良的后果.
程序例子
业务还是以打印机的程序来举例子. 打印机在打印的时候, 会有加墨水, 加纸, 打印的三个过程, 按照 (03. 单一功能原则)[https://www.jianshu.com/p/5d031e0b33a7] 的定义, 我们定义了三个接口.
- interface IPrinter {
- void addInk(IInk ink);
- void addPaper(IPaper paper);
- void print()
- }
那如果假设, 我们又一次面临打印机的升级, 打印机不仅仅能够通过空气的雾霾来合成墨水了, 而且还能通过灰尘来合成纸张, 完全不需要用户去加墨水, 加纸. 那如果我们的接口不变, 我们会面临什么问题?
我们先写一下打印机的实现.
- public class CanonPrinter implements IPrinter {
- @Override
- public void addInk(IInk ink) {
- System.out.println("使用"+ink+"进行打印");
- }
- @Override
- public void addPaper(IPaper paper) {
- System.out.println("使用"+paper+"进行打印");
- }
- @Override
- public void print() {
- addInk(new BlackInk());
- addPaper(new A4Paper());
- System.out.println("使用黑色的墨水和 A4 纸打印文档");
- }
- }
当我们实现调用的时候, 我们会写这样的代码:
- public class Main {
- public static void main(String[] args) {
- IPrinter printer = new CanonPrinter();
- printer.addInk(new RedInk());
- printer.addPaper(new A3Paper());
- printer.print();
- }
- }
当调用方运行的时候, 明明使用了红色的墨水和 A3 纸, 但是很不幸的是, 打印出来的文档居然是使用了黑色墨水和 A4 纸的打印的, 呵, 什么破打印机.
那怎么改?
很简单, 把 addInk 和 addPaper 去掉就好了.
- interface IPrinter {
- void print()
- }
- public class CanonPrinter implements IPrinter {
- private void addInk(IInk ink) {
- System.out.println("使用"+ink+"进行打印");
- }
- private void addPaper(IPaper paper) {
- System.out.println("使用"+paper+"进行打印");
- }
- @Override
- public void print() {
- addInk(new BlackInk());
- addPaper(new A4Paper());
- System.out.println("使用黑色的墨水和 A4 纸打印文档");
- }
- }
那么调用方就只需要调用 print 方法就可以了, 哈哈, 高科技.
https://www.jianshu.com/p/f59e3f1b0968
来源: http://www.jianshu.com/p/f59e3f1b0968