您的位置:首页 > 编程语言 > Java开发

《java与模式》笔记(七) 迪米特法则

2006-08-21 22:52 253 查看
☆ 迪米特法则,又叫最少知识原则,就是说,一个对象应当对其他对象有尽可能少的了解。

ξ 11.1 迪米特法则的各种表述
① 只与你直接的朋友们通信;
② 不要跟“陌生人”说话;
③ 每一个软件单位对其他的单位都只有最少的知识,而且局限于那些与本单位密切相关的软件单位。

ξ 11.2 狭义的迪米特法则
☆ 如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中的一个类需要调用另外一个类的某一个方法,可以通过第三者转发这个调用。
参考下例,Someone、Friend和Stranger三个类。



Someone类有一个方法接受一个Friend类型的变量:


public class Someone




...{


public void operation1( Friend friend )




...{


Stranger stranger = friend.provide() ;


stranger.operation3() ;


}


}



所以Someone和Friend是朋友类(直接通讯的类)。
同理,Friend类持有一个Stranger类的私有对象,他们是朋友类:


public class Friend




...{


private Stranger stranger = new Stranger() ;




public void operation2()...{}


public Stranger provide()




...{


return stranger ;


}


}



在这里,Someone类和Stranger类不是朋友类,但Someone类却通过Friend类知道了Stranger类的存在,这显然违反迪米特法则。
现在,我们对Someone和Friend类进行重构。首先在Friend类里添加一个方法,封装对Stranger类的操作:


public class Friend




...{


private Stranger stranger = new Stranger() ;




public void operation2()...{}


public Stranger provide()




...{


return stranger ;


}




public void forward()




...{


stranger.operation3() ;


}


}





然后,我们重构Someone的operation1方法,让其调用新提供的forward方法:


public class Someone




...{


public void operation1( Friend friend )




...{


friend.forward() ;


}


}



现在Someone对Stranger的依赖完全通过Friend隔离,这样的结构已经符合狭义迪米特法则了。
仔细观察上述结构,会发现狭义迪米特法则一个明显的缺点:会在系统里造出大量的小方法,散落在系统的各个角落。这些方法仅仅是传递间接的调用,因此与系统的商务逻辑无关,当设计师试图从一张类图看出总体的框架时,这些小的方法会造成迷惑和困扰。遵循迪米特法则会使一个系统的局部设计简化,因为每一个局部都不会和远距离的对象有直接关联。但是,这也会造成系统的不同模块之间的通信效率降低,也会使系统的不同模块之间不容易协调。
结合依赖倒转原则,我们对代码进行如下重构来解决这个问题,首先添加一个抽象的Stranger类,使Someone依赖于抽象的“Stranger”角色,而不是具体实现:


public abstract class AbstractStranger




...{


abstract void operation3() ;


}



然后,让Stranger从该类继承:


public class Stranger extends AbstractStranger




...{




public void operation3() ...{}


}



随后,我们重构Someone使其依赖抽象的Stranger角色:


public class Someone




...{


public void operation1( Friend friend )




...{


AbstractStranger stranger = friend.provide() ;


stranger.operation3() ;


}


}



最后,我们重构Friend的provide方法,使其返回抽象角色:


public class Friend




...{


private Stranger stranger = new Stranger() ;




public void operation2()...{}


public AbstractStranger provide()




...{


return stranger ;


}


}



现在,AbstractStranger成为Someone的朋友类,而Friend类可以随时替换掉AbstractStranger的实现类,Someone不再需要了解Stranger的内部实现细节。下图是重构后的UML类图:



ξ 11.3 迪米特法则与设计模式
对迪米特法则的最好描述,可以参考门面模式和调停者模式。

ξ 11.4 广义迪米特法则
☆ 在将迪米特法则运用到系统的设计中时,应注意的几点:
① 在类的划分上,应该创建有弱耦合的类;
② 在类的结构设计上,每一个类都应当尽量降低成员的访问权限;
③ 在类的设计上,只要有可能,一个类应当设计成不变类;
④ 在对其他类的引用上,一个对象对其它对象的引用应当降到最低;
⑤ 尽量降低类的访问权限;
⑥ 谨慎使用序列化功能;
⑦ 不要暴露类成员,而应该提供相应的访问器(属性)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: