您的位置:首页 > 其它

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

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



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



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



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

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

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

个人的理解:

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

下面看这样的一个例子:

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

直接看代码:

佣人:



[java] view
plain copy

public class Maid {

private String maidName;

public Maid() {

super();

}

public Maid(String maidName) {

super();

this.maidName = maidName;

}

public void cook(){

System.out.println(this.maidName + ">>做饭!");

}

}

管家:

[java] view
plain copy

public class Butler {

public void cook(List<Maid> maidList){

for (Maid maid : maidList) {

maid.cook();

}

}

}

主人:

[java] view
plain copy

public class Master {

public void cookCommand(Butler butler){

List<Maid> maidList = new ArrayList<Maid>();

for(int i = 0; i < 2; i++){

maidList.add(new Maid("maid" + i));

}

butler.cook(maidList);

}

}

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

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

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

[java] view
plain copy

public class Master {

public void cookCommand(Butler butler){

butler.cook();

}

}

[java] view
plain copy

public class Butler {

public List<Maid> getMaidList(){

List<Maid> maidList = new ArrayList<Maid>();

for(int i = 0; i < 2; i++){

maidList.add(new Maid("maid" + i));

}

return maidList;

}

public void cook(){

List<Maid> maidList = getMaidList();

for (Maid maid : maidList) {

maid.cook();

}

}

}

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

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

源代码:源代码下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: