定义:
一个对象应该对其它的对象保持最少的了解。迪米特法则又称为最少知识法则,英文全称为Least Knowledge Principle ,简称为LKP。
个人理解:
迪米特法则主要目的是类间解耦,弱耦合。只有类弱耦合了后,类的复用性才会提高。
问题由来:
类之间的关系越密切,类之间的耦合程度越高。当一个类发改变时,耦合度越大,对另一类的影响也就越大。
解决方案:
尽量降低类之间的耦合度。
从事编程的都知道,软件编程总的原则是低耦合、高内聚,只有这样才能提高代码的复用率,而这正是迪米特法则所要求的。迪米特法则还有一个更简单的定义:只与直接的朋友通信。首先来解释一下什么是直接的朋友:每个对象都会与其他对象有耦合关系,只要两个对象之间有耦合关系,我们就说这两个对象之间是朋友关系。耦合的方式很多,依赖、关联、组合、聚合等。其中,我们称出现成员变量、方法参数、方法返回值中的类为直接的朋友,而出现在局部变量中的类则不是直接的朋友。也就是说,陌生的类最好不要作为局部变量的形式出现在类的内部。
举例说明:
老师(Teacher类)对组长(GroupLeader类)发布命令,组长对女生(Gril类)人数统计并输出来。违反迪米特法则的代码如下所示:
public class Girl { } public class GroubLeader { //有清查女生的工作 public void CountGrilNumber(List<Girl> girlslist) { Console.WriteLine("女生的数量是"+girlslist.Count); } } public class Teacher { public void Command(GroubLeader groubLeader) { var grilList = new List<Girl>(); //初始化女生列表 for (var i = 0; i < 30; i++) { grilList.Add(new Girl()); } //告诉体育委员要清查女生数量 groubLeader.CountGrilNumber(grilList); } } class Client { static void Main(string[] args) { var teacher = new Teacher(); //老师发布命令 teacher.Command(new GroubLeader()); Console.ReadKey(); } }
上面的代码中Teacher初始化了Gril的List列表,老师直接操作女生的列表这显然不符合常规,更不符合迪米特法则,正常的顺序是老师对组长发布命令,组长统计女生人数。类的关系要尽量的解耦,降低他们的耦合度。改进方法是GroupLeader内部私有化一个List<Gril>变量,在构造GroupLeader变量时传递List<Gril>参数,这样就降低了Gril和GroupLeader的耦合度。改进代码如下所示:
public class Girl { } public class GroubLeader { private readonly List<Girl> _girList; public GroubLeader(List<Girl> girlList) { _girList = girlList; } //有清查女生的工作 public void CountGrilNumber() { Console.WriteLine("女生的数量是" + _girList.Count); } } public class Teacher { public void Command(GroubLeader groubLeader) { //告诉体育委员要清查女生数量 groubLeader.CountGrilNumber(); } } class Client { static void Main(string[] args) { var girlList = new List<Girl>(); //初始化女生列表 for (var i = 0; i < 30; i++) { girlList.Add(new Girl()); } var teacher = new Teacher(); //老师发布命令 teacher.Command(new GroubLeader(girlList)); Console.ReadKey(); } }
上面的例子只是单纯的说明迪米特法则的使用,可能有些牵强,关键还是理解一个对象应尽量对其它对象保持少的了解这句话的意思。