设计模式之禅笔记--面向对象设计六大原则之五

来源:互联网 发布:何以知之的以 编辑:程序博客网 时间:2024/05/22 14:41

第五章  迪米特法则(LoD/LKP)

定义:

迪米特法则( Law of Demeter,LoD) 也称为最少知识原则( Least KnowledgePrinciple, LKP):

l  一个对象应该对其他对象有最少的了解。

解释:

迪米特法则对类的低耦合提出了明确的要求, 其包含以下4层含义。

1) 只和朋友交流

n  迪米特法则还有一个英文解释是: Only talk to your immediate friends( 只与直接的朋友通信。 )。每个对象都必然会与其他对象有耦合关系,两个对象之间的耦合就成为朋友关系, 这种关系的类型有很多, 例如组合、 聚合、 依赖等。

n  朋友类的定义是: 出现在成员变量、 方法的输入输出参数中的类称为成员朋友类, 而出现在方法体内部的类不属于朋友类。

n  注意:一个类只和朋友交流, 不与陌生类交流,不要有getA().getB().getC().getD()这种情况( 在一种极端的情况下允许出现这种访问, 即每一个点号后面的返回类型都相同) ,类与类之间的关系是建立在类间的, 而不是方法间, 因此一个方法尽量不引入一个类中不存在的对象, 当然, JDK API提供的类除外

n  例子:



场景:老师想让体育委员确认一下全班女生来齐没有, 就对他说: “你去把全班女生清一下。

问题:Girl类只出现在commond方法体内, 因此不属于Teacher类的朋友类。


解决办法:

在类图中去掉Teacher对Girl类的依赖关系。在GroupLeader类中定义了一个构造函数, 增加了对Girl的注入,通过构造函数传递了Girl类依赖关系。


 

2) 朋友间也是有距离的

n  迪米特法则就是对这个距离进行描述, 即使是朋友类之间也不能无话不说,无所不知。

n  注意: 迪米特法则要求类“羞涩”一点, 尽量不要对外公布太多的public方法和非静态的public变量,尽量内敛, 多使用private、 package-private、 protected等访问权限。

n  例子:

场景:安装软件的时候, 经常会有一个导向动作, 第一步是确认是否安装, 第二步确认License, 再然后选择安装目录。  

问题:Wizard类把太多的方法暴露给InstallSoftware类, 两者的朋友关系太亲密了, 耦合关系变得异常牢固,从而把修改变更的风险扩散开了。


解决办法:

将三个步骤的访问权限修改为private, 同时把InstallSoftware中的方法installWizad移动到Wizard方法中。Wizard类就只对外公布了一个public方法。


 

3) 是自己的就是自己的

n  在实际应用中经常会出现这样一个方法:放在本类中也可以, 放在其他类中也没有错,那怎么去衡量呢?

如果一个方法放在本类中, 既不增加类间关系,也对本类不产生负面影响, 那就放置在本类中。

4) 谨慎使用Serializable

n  举个例子来说, 在一个项目中使用RMI( Remote Method Invocation, 远程方法调用)方式传递一个VO( Value Object, 值对象) , 这个对象就必须实现Serializable接口( 仅仅是一个标志性接口, 不需要实现具体的方法) , 也就是把需要网络传输的对象进行序列化,否则就会出现NotSerializableException异常。 突然有一天, 客户端的VO修改了一个属性的访问权限, 从private变更为public, 访问权限扩大了, 如果服务器上没有做出相应的变更, 就会报序列化失败, 就这么简单。 但是这个问题的产生应该属于项目管理范畴,一个类或接口在客户端已经变更了, 而服务器端却没有同步更新, 难道不是项目管理的失职吗?

最佳实践

l  迪米特法则的核心观念就是类间解耦, 弱耦合, 只有弱耦合了以后, 类的复用率才可以提高。

n  其要求的结果就是产生了大量的中转或跳转类,导致系统的复杂性提高, 同时也为维护带来了难度。

n  采用迪米特法则时需要反复权衡, 既做到让结构清晰,又做到高内聚低耦合。

l  在实际应用中, 如果一个类跳转两次以上才能访问到另一个类, 就需要想办法进行重构。 因为跳转次数越多, 系统越复杂, 维护就越困难。

l  在实际的项目中, 需要适度地考虑这个原则,别为了套用原则而做项目。

n  原则只是供参考,不遵循是不对的, 严格执行就是“过犹不及”,需要大家在采用原则时反复度量。

阅读全文
0 0
原创粉丝点击