引言
本文参考以下这篇文章
java设计模式4,不要和陌生人说话_不要和陌生人说话 设计模式_哪 吒的博客-CSDN博客
迪米特法则 (Law of Demeter)_小风的笔记的博客-CSDN博客_迪米特法则
个人总结
项目总监 -> 员工
项目总监 -> 项目经理 -> 员工
项目总监如果仅仅想知道部分员工的工作情况(如男员工的工作情况)
项目总监不应该亲自先去统计哪些员工是男员工,获取男员工的所有信息,再依次获取男员工的工作情况
(因为项目总监仅仅是想知道员工工作情况,而不是员工的所有信息;同时,项目总监的工作也不应该包含统计员工信息的工作)
此时项目总监可以安排项目经理负责统计男员工的员工信息
项目经理可以负责统计员工信息,如:筛选出来男员工的所有信息,再筛选出来男员工的工作情况,提取成方法,提供给项目总监使用
优点:
如果某一天,项目经理想要知道所有女员工的请假情况,
按照原始方案,项目总监需要亲自统计所有女员工以及女员工的请假情况
(结果是:项目总监这个类会不断被扩张,修改)
如果将这个任务交给项目经理,就有很多种设计方案可以选择
①让现有的项目经理新增统计女员工请假状况的功能,提供给项目总监使用
②新增统计女员工请假状况的项目经理,负责提供功能给项目总监
项目总监 -> 项目经理A(负责统计所有男员工的工作情况)& 项目经理B(负责统计所有女员工的请假情况)-> 员工信息
缺点
过度使用迪米特法则会使系统产生大量的中介类,从而增加系统的复杂性,使模块之间的通信效率降低。
所以,在釆用迪米特法则时需要反复权衡,确保高内聚和低耦合的同时,保证系统的结构清晰。
补充
以前端封装组件为例
①现有element-plus的组件drawer
②我们想在一个模块中(如图库管理ImageManage.vue)使用drawer的弹窗功能
现在有两种方案:
①直接在ImageManage.vue中引用这个drawer(ImageManage -> drawer)
②新建ImageDrawer,封装drawer(ImageManage -> ImageDrawer -> drawer)
分析:
方案一的缺点:
①组件需要直接使用drawer的属性和方法,假设还有n个模块,也要直接用到drawer,(userManage -> drawer),如果有一天官方通知drawer某个属性/方法被废弃了,那我们需要依次到这些模块(ImageManage、UserManage等等)中修改这些属性
结果:因为一个改动,需要修改n个地方
②如果需要给drawer扩展功能,例如添加渐变色功能,按照现有的逻辑,要么修改模块组件ImageManage,要么修改drawer;如果修改ImageManage,那么同理UserManage添加变色功能也要copy同样一份代码,会造成一定的代码冗余;
③如果需要给drawer扩展功能,那么假设UserManage需要渐变色功能,而ImageManage需要图片上传功能,那需要同时给drawer添加这两个功能;现在看起来还好,改动不大,如果需要添加10个毫不相关的功能,那么drawer的代码会非常庞大,并且在使用的时候,还需要初始化很多属性
方案二是如何解决方案一的缺点的:
①可以新建CommonDrawer,让 ImageManage/UserManage -> CommonDrawer -> drawer都经过一层处理,这样的话如果drawer修改了某个属性/方法,我们只需要改动少量的代码(这里只需要修改CommonDrawer)即可
②同上,添加CommonDrawer,在CommonDrawer中实现这个功能
③可以创建CommonDrawer和FileUploadDrawer,将两个毫不相关的功能封装在不同的drawer中,
这样也利于以后代码的维护
补充总结
可以看到,最少知道原则可以很好地消除部分业务上的代码耦合,利于代码维护;
但是缺点也很明显,会在项目中产生很多中间组件,有时不同的中间组件可能包含相同的功能和方法,这样会造成一定的代码冗余