首页 学海无涯 程序设计 面向对象程序设计六大原则:迪米特法则
面向对象程序设计六大原则:迪米特法则
摘要 一个类对于其他类知道得越少越好。

迪米特法则(Law of Demeter)(LOD)

定义

一个类对于其他类知道得越少越好。从被依赖方的角度来说,暴露的东西越少越好。

意义

迪米特法则是为了降低类与类之间的耦合,每个类都尽量减少对其他类的依赖,使类与类之间的影响降到最低。

案例讲解

还是老样子,对于程序设计思想这种抽象的东西,就好的理解方式就是通过案例。

需求:

学校管理系统中,学校对班级和学生的管理功能。

不好的设计(违背迪米特法则):

/// <summary>
/// 学校
/// </summary>
internal class School
{
public ICollection<Class>? Classes { get; set; }
/// <summary>
/// 点名
/// </summary>
public void CallName()
{
if (Classes == null)
return;
foreach (var item in Classes)
{
Console.WriteLine("查找班级中的学生");
if (item.Students == null)
return;
foreach (var student in item.Students)
{
student.Report();
}
}
}
}

/// <summary>
/// 班级
/// </summary>
internal class Class
{
public ICollection<Student>? Students { get; set; }
}

/// <summary>
/// 学生
/// </summary>
internal class Student
{
public Student(string name)
{
Name = name;
}
public string Name { get; set; }
/// <summary>
/// 报道
/// </summary>
public void Report()
{
Console.WriteLine($"{Name} 前来报道");
}
}

上面的设计不好的地方在于,学校类既依赖班级类又依赖学生类,班级将学生的细节暴露出来,使学校知道了班级中学生的存在,并对学生产生了依赖关系。违背了迪米特法则:对于其他类知道得越少越好

较好的设计(遵循迪米特法则):

/// <summary>
/// 学校
/// </summary>
internal class School
{
public ICollection<Class>? Classes { get; set; }
/// <summary>
/// 点名
/// </summary>
public void CallName()
{
if (Classes == null)
return;
foreach (var item in Classes)
{
Console.WriteLine("班级自己负责点名");
item.CallName();
}
}
}

/// <summary>
/// 班级
/// </summary>
internal class Class
{
private ICollection<Student>? Students { get; set; }
public void CallName()
{
if (Students == null)
return;
foreach (var student in Students)
{
student.Report();
}
}
}

将Student点名的动作交给Class类自己处理,Class类的Students属性设置为私有,不再暴露给School类,School类执行CallName方法的结果没有任何变化,但是School类和Student类之间已经不存在依赖关系。

迪米特法则还有种说法:只和直接朋友通信,不和陌生人说话

什么叫直接朋友?一般将类中定义的属性全局变量,方法传入的参数返回值等对象视为直接朋友,否则就是陌生人。比如School类中定义了Classes属性,那么Class类就是直接朋友,而Student类和School类并没有直接联系,School类只负责对Class类进行管理,而对Student的管理是Class类的责任。School类不需要对Student类进行直接操作,就不应该知道Student类的存在,这样School类和Student类就不会出现耦合。

几个心得

1.在设计类时,尽量降低类和成员的访问修饰符权限。

2.在方法内部,尽量避免使用陌生类的实例(局部变量)。

3.在遵循迪米特法则的过程中可能会产生许多的中介类,增加系统的复杂度,使类与类之间通信效率变低。所以在实际使用过程中,需要权衡利弊,在满足高内聚、低耦合的同时,保证系统结构清晰。

4.迪米特法则不仅适用于类与类之间的关系,也适用于类库/模块之间的关系:比如常见的三层系统架构,UI层(显示层)不应该和DAL层(数据访问层)有依赖关系。

结语

迪米特法则相对来说比较容易理解,但是使用起来也需要经验的积累,过度使用也会带来麻烦。

版权声明:本文由不落阁原创出品,转载请注明出处!

本文链接:http://www.leo96.com/article/detail/85

广告位

来说两句吧
最新评论

暂无评论,大侠不妨来一发?