设计模式学习之——六大设计原则之五:迪米特法则
来源:互联网 发布:sql语句查询两张表 编辑:程序博客网 时间:2024/06/03 21:36
迪米特法则又称最少知识原则(Least Knowledge Principle, LKP)
解释1:一个对象应对其他对象有最少的了解
解释2:Only talk to your immedate friends(只与直接的朋友通信)
对类的低耦合提出明确要求:(4点)
1.只和朋友交流
eg:
老师教班长去清点班中女生人数(在老师类中初始化女生)
老师类:
- public class Teacher
- {
- //老师对班长发布命令,清点女生
- public void commond(GroupLeader groupLeader)
- {
- List<Girl> listGirls = new ArrayList();
- //初始化女生
- for (int i = 0; i < 20; i++)
- {
- listGirls.Add(new Girl());
- //告诉班长开始执行清点任务
- groupLeader.countGirls(listGirls);
- }
- }
- }
- public class GroupLeader
- {
- //清点女生数量
- public void countGirls(List<Girl> listGirls)
- {
- //输出女生数量:listGirls.size()
- }
- }
- public class Girl
- {
- }
- public class Client
- {
- public static void main(String[] args)
- {
- Teacher teacher = new Teacher();
- //老师发布命令
- teacher.commond(new GroupLeader());
- }
- }
运行结果是:20
考虑程序中存在的问题:
先考虑Teacher类有几个朋友类?它仅有一个朋友类GroupLeader,为什么Girl不是朋友类呢?
朋友类的定义:出现在成员变量、方法的输入输出参数中的类称为成员朋友类,而出现在方法体内部的类不属于朋友类。
现在我们看,Girl类就是出现在commond方法体内的,所以说 不属于Teacher类的朋友类。
所以,我们需要修改类关系图:
修改后的老师类:
- public class Teacher
- {
- //老师对班长发布命令,清点女生
- public void commond(GroupLeader groupLeader)
- {
- //告诉班长开始执行清点任务
- groupLeader.countGirls();
- }
- }
- public class GroupLeader
- {
- private List<Girl> listGirls;
- public GroupLeader(List<Girl> _listGirls)
- {
- this.listGirls = _listGirls;
- }
- //清点女生数量
- public void countGirls(List<Girl> listGirls)
- {
- //输出女生数量:this.listGirls.size()
- }
- }
- public class Client
- {
- public static void main(String[] args)
- {
- //产生一个女生群体
- List<Girl> listGirls = new ArrayList<Girl>();
- //初始化女生
- for (int i = 0; i < 20; i++)
- {
- listGirls.Add(new Girl());
- }
- Teacher teacher = new Teacher();
- //老师发布命令
- teacher.commond(new GroupLeader(listGirls));
- }
- }
简单修改程序,将Teacher中对女生的初始化放到了场景类中,同时在GroupLeader中增加了对Girl的注入,避开了Teacher类对陌生类Girl的访问,降低了系统间的耦合,提高了系统的健壮性。
注意:一个类只和朋友交流,不与陌生类交流,不要出现 getA().getB().getC().getD() 这种情况(除非每个点号后面的返回类型都相同),类与类间的关系是建立在类间的,而不是方法间的
2. 朋友间也是有距离的
eg:
安装软件时,会有导向动作,第一步做什么,第二步做什么等等,即是顺序执行。具体到程序中就是:调用一个或多个类,先执行第一个方法,然后第二个方法根据返回结果再来看是否可以调用第三个方法。
类关系图:
导向类:
- public class Wizard
- {
- private Random rand = new Random(System.currentTimeMillis());
- public int first()
- {
- //执行第一个方法
- return rand.nextInt(100);
- }
- public int second()
- {
- //执行第二个方法
- return rand.nextInt(100);
- }
- public int third()
- {
- //执行第三个方法
- return rand.nextInt(100);
- }
- }
InstallSoftware类:
- public class InstallSoftware
- {
- public void installWizard(Wizard wizard)
- {
- int first = wizard.first();
- if (first > 50)
- {
- int second = wizard.second();
- if (second > 50)
- {
- int third = wizard.third();
- if (third > 50)
- wizard.first();
- }
- }
- }
- }
- public class Client
- {
- public static void main(String[] args)
- {
- InstallSoftware invoker = new InstallSoftware();
- invoker.installWizard(new Wizard());
- }
- }
现在,我们可以来看下程序中存在什么问题?Wizard把太多的方法暴露给InstallSoftware类,两者朋友类关系太亲密了,耦合关系变得异常牢固。
此时如果我们要将Wizard类中的first方法返回值的类型由int修改为boolean的话,就需要修改InstallSoftware类,从而把修改变更的风险扩散了。
因此这样的耦合是季度不合适的,重新设计吧!!重构后如下图:
在Wizard类中增加一个installWizard方法,对安装过程进行封装,同时,把原有的三个public方法改成private方法
修改后的导向类如下:
- public class Wizard
- {
- private Random rand = new Random(System.currentTimeMillis());
- private int first()
- {
- //执行第一个方法
- return rand.nextInt(100);
- }
- private int second()
- {
- //执行第二个方法
- return rand.nextInt(100);
- }
- private int third()
- {
- //执行第三个方法
- return rand.nextInt(100);
- }
- //软件安装过程
- public void installWizard()
- {
- int first = wizard.first();
- if (first > 50)
- {
- int second = wizard.second();
- if (second > 50)
- {
- int third = wizard.third();
- if (third > 50)
- wizard.first();
- }
- }
- }
- }
少量修改InstallSoftware类
- public class InstallSoftware
- {
- public void installWizard(Wizard wizard)
- {
- //直接调用
- wizard.installWizard();
- }
- }
3. 自己的就是自己的
原则:如果一个方法放在本类中,即不增加类间关系,也对本类不产生负面影响,就放置在本类中。
4. 谨慎使用Serializable
这个是项目管理的问题咯。小码农不考虑,略~
欢迎转载,转载注明出处,谢谢
Mr.傅:阅读自《设计模式之禅》
来源:http://blog.csdn.net/fu222cs98/article/details/21426339
0 0
- 设计模式学习之——六大设计原则之五:迪米特法则
- 设计模式学习之——六大设计原则之五:迪米特法则
- 设计模式学习之——六大设计原则之五:迪米特法则
- 设计模式六大原则之五:迪米特法则
- 设计模式六大原则之迪米特法则
- 设计模式笔记(五)设计六大原则之五--迪米特法则
- 设计模式六大原则之--迪米特法则(LoD)
- 设计模式之六大原则——迪米特法则(LoD,LKP)
- 设计模式之六大原则——迪米特法则(LoD,LKP)
- 设计模式之六大原则——迪米特法则(LoD,LKP)
- 设计模式之六大原则——迪米特法则(LoD,LKP)
- 设计模式之六大原则——迪米特法则(LoD,LKP)
- 设计模式之六大原则——迪米特法则(LoD,LKP)
- 设计模式之——六大原则
- 设计模式六大原则——迪米特法则(LoD)
- 设计模式六大原则——迪米特法则
- 设计模式学习之——六大设计原则之二:里氏替换原则
- 设计模式学习之——六大设计原则之三:依赖倒置原则
- if else 这点事
- HDU 1598 find the most comfortable road (枚举+Kruskal)
- 出现在嵌入式DSP上可用于实现各种编解码器
- 每天一个小程序(9)——链队
- showDialog IE与火狐兼容问题
- 设计模式学习之——六大设计原则之五:迪米特法则
- Haar 分类器
- KMP字符串模式匹配
- android Dalvik虚拟机
- android 程序控制GPS WIFI 蓝牙
- 淘金网络Voip网络电话的概述
- Search Insert Position
- MySQL存储过程详解 mysql 存储过程
- ISE 14.4初级入门——02