"围观"设计模式(5)--迪米特法则(Lod,Law of Demeter)或最少知道原则(Least Knowledge Principle)

得墨忒耳(迪米特)定律(Law of Demeter,缩写LoD)亦称为“最少知识原则(Principle of Least Knowledge)”,是一种软件开发的设计指导原则,特别是面向对象的程序设计。得墨忒耳(迪米特)定律是松耦合的一种具体案例。该原则是美国东北大学在1987年末在发明的,可以简单地以下面任一种方式总结:

    1. 每个单元对于其他的单元只能拥有有限的知识:只是与当前单元紧密联系的单元;

    2. 每个单元只能和它的朋友交谈:不能和陌生单元交谈;

    3. 只和自己直接的朋友交谈。

这个原理的名称来源于希腊神话中的农业女神,孤独的得墨忒耳。

很多面向对象程序设计语言用"."表示对象的域的解析算符,因此得墨忒耳定律可以简单地陈述为“只使用一个.算符”。因此,a.b.Method()违反了此定律,而a.Method()不违反此定律。一个简单例子是,人可以命令一条狗行走(walk),但是不应该直接指挥狗的腿行走,应该由狗去指挥控制它的腿如何行走。----WIKIPIDIA


个人的理解:

面向对象的程序设计中,对象与对象之间尽量相互独立,具体对象的行为由具体的对象去完成,而不是由某个对象去指定另一个对象去实施行为而且是具体的行为。迪米特法则,核心的思想就是,要求我们在设计的时候,尽量避免类与类之间的耦合,弱化耦合关系可以提升复用率,但是这样的话,会产生中间的跳转类等,导致系统复杂。实际使用的过程中尽量在保证可读性与复杂性较低的情况下,按照迪米特法则去弱化类与类之间的耦合关系(高内聚、低耦合)。


下面看这样的一个例子:


场景介绍:想象一下,你是这家的主人,雇佣了管家帮你安排一些家务事,还雇佣了一些佣人去帮你完成管家吩咐的家务事。你想吃饭,这时候,需要向管家吩咐一下,然后你就不需要管了,具体谁去做饭这不需要你去关系,你只需要知道,待半个小时左右,我看到餐桌上有饭,你可以去品尝就好了,这样才是比较合理的事情。


直接看代码:

佣人:

[java]  view plain  copy
  1. public class Maid {  
  2.   
  3.     private String maidName;  
  4.       
  5.     public Maid() {  
  6.         super();  
  7.     }  
  8.   
  9.     public Maid(String maidName) {  
  10.         super();  
  11.         this.maidName = maidName;  
  12.     }  
  13.   
  14.     public void cook(){  
  15.         System.out.println(this.maidName + ">>做饭!");  
  16.     }  
  17.       
  18. }  
管家:

[java]  view plain  copy
  1. public class Butler {  
  2.   
  3.     public void cook(List<Maid> maidList){  
  4.         for (Maid maid : maidList) {  
  5.             maid.cook();  
  6.         }  
  7.     }  
  8. }  
主人:

[java]  view plain  copy
  1. public class Master {  
  2.   
  3.     public void cookCommand(Butler butler){  
  4.         List<Maid> maidList = new ArrayList<Maid>();  
  5.         for(int i = 0; i < 2; i++){  
  6.             maidList.add(new Maid("maid" + i));  
  7.         }  
  8.           
  9.         butler.cook(maidList);  
  10.     }  
  11. }  

问题来了,这里的设计的时候,是不是太不合理了,你作为一个主人,管的太多了,因为你要去创建好一些佣人,交给管家去吩咐,这个任务对你来说显然是多余的,因为有管家在,你不用去做这么多事情,你只需要跟管家说,管家,我想吃点东西,管家接到命令之后,去找来几个佣人,然后去给你做饭。这样才是好的设计。


上面的这个设计违背了迪米特法则,因为,Master与Butler、Maid是层级的关系,在Master这个类中,只需要去管理Butler而Butler中去管理Maid,通俗来说是Master给Butler吩咐任务,Butler接到任务后然后再给Maid分配任务。


我们按照这个思路再来设计一下上面的例子。


[java]  view plain  copy
  1. public class Master {  
  2.   
  3.     public void cookCommand(Butler butler){  
  4.         butler.cook();  
  5.     }  
  6. }  

[java]  view plain  copy
  1. public class Butler {  
  2.   
  3.     public List<Maid> getMaidList(){  
  4.         List<Maid> maidList = new ArrayList<Maid>();  
  5.         for(int i = 0; i < 2; i++){  
  6.             maidList.add(new Maid("maid" + i));  
  7.         }  
  8.         return maidList;  
  9.     }  
  10.       
  11.     public void cook(){  
  12.         List<Maid> maidList = getMaidList();  
  13.         for (Maid maid : maidList) {  
  14.             maid.cook();  
  15.         }  
  16.     }  
  17. }  

这样设计的话,你会发现,Master不用跟Maid打交道,而是和Butler打交道,这样的话,减少了类与类之间不必要的耦合,使得系统更稳定,扩展更容易。


根据迪米特法则设计类的时候,尽量降低非朋友类之间的耦合。

源代码:源代码下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值