六大原则之“迪米特法则(LoD)“笔记

1.迪米特法则:Law of Demeter, LoD),也称最少知识原则(Least Knowledge Principle, LKP)

定义:Only talk to your immedate friends.(只与直接的朋友通信)。一个对象应该对其他对象有最少的了解。(通俗地讲,一个类应该对自己需要耦合或调用的类知道得最少)


2.理解:

2.1 只和朋友交流(更准确来讲是:直接的朋友)

每个对象都必然会与其他对象有耦合关系,两个对象之间的耦合就成为朋友关系,这种关系的类型有很多,如组合、聚合、依赖等。
朋友类的定义:出现在成员变量、方法的输入输出参数中的类。   而方法体类内部的类不能算。
2.2 朋友之间也有间距
如果朋友把太多的方法或属性暴露给你,则过于亲密,耦合关系变得异常牢固,而且,修改时涉及的面也就越大,变更引起的风险就越大。因此,要适时反复衡量:是否可以减少public方法和属性,改为private、package-private、protected等访问权限,及是否可以加上final关键字。

3.问题由来:
类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大。[解决方案]尽量降低类与类之间的耦合。

4.使用LoD的好处:
  1. 降低类与类之间的耦合。

5.难点:
  • LoD法则的核心就是类间解耦,弱耦合,但实现过程则是通过“朋友类”来中转,结果就是产生了大量的中转或跳转类,导致系统的复杂性提高,增加了维护的难度。一个准则:只要跳转不超过两次都是可以忍受的,反之则要考虑重构;
  • LoD法则要求解耦,但解耦是有限度的,原则仅供参考,严格执行就是“过犹不及”。

6.最佳实践:
  • ① 在类的划分上,应该创建有弱耦合的类;
    ② 在类的结构设计上,每一个类都应当尽量降低成员的访问权限;
    ③ 在类的设计上,只要有可能,一个类应当设计成不变类;
    ④ 在对其他类的引用上,一个对象对其它对象的引用应当降到最低;
    ⑤ 尽量降低类的访问权限;
    ⑥ 谨慎使用序列化功能(类或接口在客户端变更,却未在服务端同步更新,引发序列化失败,,项目管理易疏忽);
    ⑦ 不要暴露类成员,而应该提供相应的访问器(属性)

在实际应用中经常会出现这样一个方法:放在本类中也可以,放在其他类中也没有问题,怎么去衡量呢?建议:如果一个类放在本类中,既不增加类间关系,又不对本类产生不负面影响,就放置在本类中。


7.范例:

7.1  一个常态的编程(肯定是不符LoD的反例)

//体育老老师让体委清点全班女生个数。类图如下:


对应源代码如下:

[java]  view plain copy
  1. public class Teacher {  
  2.     //老师对学生发布命令,清一下女生  
  3.     public void commond(GroupLeader groupLeader){  
  4.         List<Girl> listGirls = new ArrayList();  
  5.         //初始化女生  
  6.         for(int i=0;i<20;i++){  
  7.             listGirls.add(new Girl());  
  8.         }  
  9.         //告诉体育委员开始执行清查任务  
  10.         groupLeader.countGirls(listGirls);  
  11.     }  
  12. }  
  13.   
  14. public class GroupLeader {  
  15.     //有清查女生的工作  
  16.     public void countGirls(List<Girl> listGirls){  
  17.         System.out.println("女生数量是:"+listGirls.size());  
  18.     }  
  19. }  
  20.   
  21. public class Girl {  
  22. }  
  23.   
  24. public class Client {  
  25.     public static void main(String[] args) {  
  26.         Teacher teacher= new Teacher();  
  27.         //老师发布命令  
  28.         teacher.commond(new GroupLeader());  
  29.     }  
  30. }  

看看上面的要求:老师 让 体委  清点  女生 数目。老师与女生是陌生关系啊(老师不需要女生执行任何动作)。显然,上述做法违背LoD法则。

改如下:


7.2 依据LoD法则解耦(与真实意义上的陌生类解耦,这里而不应为上述类图中未正确体会语义的虚假朋友类Girl):


对应源码如下:

[java]  view plain copy
  1. public class Teacher {  
  2.     //老师对学生发布命令,清一下女生  
  3.     public void commond(GroupLeader groupLeader){  
  4.         //告诉体育委员开始执行清查任务  
  5.         groupLeader.countGirls();  
  6.     }  
  7. }  
  8.   
  9. public class GroupLeader {  
  10.     private List<Girl> listGirls;  
  11.     //传递全班的女生  
  12.     public GroupLeader(List<Girl> _listGirls){  
  13.         this.listGirls = _listGirls;  
  14.     }  
  15.   
  16.     //有清查女生的工作  
  17.     public void countGirls(){  
  18.         System.out.println("女生数量是:"+listGirls.size());  
  19.     }     
  20. }  
  21.   
  22. public class Girl {  
  23. }  
  24.   
  25. public class Client {  
  26.     public static void main(String[] args) {      
  27.         List<Girl> listGirls = new ArrayList<Girl>();  
  28.         //初始化女生  
  29.         for(int i=0;i<20;i++){  
  30.             listGirls.add(new Girl());  
  31.         }  
  32.       
  33.         Teacher teacher= new Teacher();  
  34.         //老师发布命令  
  35.         teacher.commond(new GroupLeader(listGirls));  
  36.     }  
  37. }  
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值