5. 迪米特法则(Law of Demeter,LoD)
5.1 定义
(1)应尽量减少其他对象之间的交互,对象只和自己的朋友交谈,即对其他依赖的类越少越好(不要和太多的类发生关系)。
(2)尽量不要让类和类之间建立直接的关系,这样可减少类与类之间的依赖,降低类之间的耦合。
(3)一个类应对自己需要耦合的类知道得最少,只知道其public方法,其内部如何复杂自己没有关系,也叫最少知识原则(Least Knowledge Principle,LKP)。
5.2 迪米特法则:核心要义就是类间解耦、低耦合
(1)只和直接朋友交流
①直接朋友的定义:出现在成员变量、方法的输入参数和返回值的类称为朋友类
②非朋友:出现在方法体内部的类
【编程实验】体育委员点名
//违反LoD的设计
//面向对象设计原则:LoD迪米特法则 //类间解耦 #include <stdio.h> #include <list> using namespace std; //Girl类 class Girl { }; //体育委员类 class GroupLeader { public: //清点女生数量 void countGirls(list<Girl>& list) { printf("Numbers of Girls: %d ", list.size()); } }; //Teacher类 class Teacher { public: //老师叫体育委员清点一下女生人数 void command(GroupLeader& groupLeader) { //方法内的类,与Teacher不是朋友关系, //但这样的设计会使Teacher对Girl类产生依赖,违反Lod法则 list<Girl> listGirls; //初始化女生 for(int i = 0; i< 20; i++) { Girl g; listGirls.push_back(g);//会复制一份过去 } groupLeader.countGirls(listGirls); } }; int main() { Teacher teacher; GroupLeader groupLeader; //老师发布命令 teacher.command(groupLeader); return 0; }
//遵循LoD法则的设计
//面向对象设计原则:LoD迪米特法则 //类间解耦 #include <stdio.h> #include <list> using namespace std; //Girl类 class Girl { }; //体育委员类 class GroupLeader { private: list<Girl>& listGirls; public: //从构造器传入全班女生 GroupLeader(list<Girl>& _list):listGirls(_list) { } //清点女生数量 void countGirls() { printf("Numbers of Girls: %d ", listGirls.size()); } }; //Teacher类:与Girl类解耦 class Teacher { public: //老师叫体育委员清点一下女生人数 void command(GroupLeader& groupLeader) { groupLeader.countGirls(); } }; int main() { Teacher teacher; list<Girl> listGirls; //初始化女生 for(int i = 0; i< 20; i++) { Girl g; listGirls.push_back(g);//会复制一份过去 } // GroupLeader groupLeader(listGirls); //老师发布命令 teacher.command(groupLeader); return 0; }
(2)朋友间也是有距离的
//知道得太多:InstallSoftware类和Wizard的耦合太紧
//松耦合:隐藏Wizard类安装步骤的接口,降低耦合度
(3)是自己的就是自己的
当某个方法放在本类可以,放在其他类也没错,那么根据迪米特法则,可以在不增加类间的关系,也不对本类产生负面影响,就放置在本类中。
5.3 最佳实践
(1)迪米特法则的核心观念就是类间解耦、弱耦合
(2)解耦是有限度的,在实际的项目中,需要适度考虑这个原则。