迪米特法则(Law Of Demeter)

什么是迪米特法则?

迪米特法则(LoD)又称最少知识原则(Least Knowledge Principle),是一种软件设计原则,主要关注对象之间的通信而非对象本身。它的核心思想是,一个对象应该尽可能少地了解其他对象的信息,避免对象之间耦合度过高,从而达到提高模块化、降低系统复杂度、提高灵活性等目的。

具体来说,迪米特法则关注的是对象之间“黑盒”的关系,即只要外部接口不变,内部实现可以自由修改,不对外暴露细节。通过迪米特法则设计的代码,减少了彼此间的耦合,提高了代码的可扩展性,降低了代码的维护成本。

迪米特法则的核心要点:

- 只与直接的朋友通信:每个对象只与它的直接朋友(属性、方法参数、方法中new的对象)通信,不和陌生人(陌生的对象)说话,这样可以降低耦合度;

- 不透露内部信息:每个对象只暴露对外必要的行为和属性,不应该暴露过多细节,否则会降低系统可扩展性;

- 谨慎使用全局变量和静态属性:全局变量和静态属性会破坏对象之间的封装性,所以应该谨慎使用。

迪米特法则应用案例

下面通过一个简单的案例来演示迪米特法则的应用。

案例描述:假设有一个班级管理系统,包含班级、学生和讲师三个类,其中班级类负责管理学生、让学生上课,讲师类负责批改作业和发布公告,学生类则负责参加上课和完成作业。

不满足迪米特法则的版本:

```python

class Classroom:

def __init__(self, teacher, students):

self.teacher = teacher

self.students = students

def attend_class(self):

for student in self.students:

student.do_class()

def assign_homework(self):

for student in self.students:

student.do_homework()

def submit_homework(self):

for student in self.students:

self.teacher.check_homework(student.homework)

def publish_announcement(self, announcement):

self.teacher.publish_announcement(announcement)

class Teacher:

def __init__(self, name):

self.name = name

def check_homework(self, homework):

print(f"{self.name} is checking homework of {homework.student_name} ({homework.content})")

def publish_announcement(self, announcement):

print(f"{self.name} published announcement: {announcement}")

class Student:

def __init__(self, name):

self.name = name

self.homework = None

def do_class(self):

print(f"{self.name} attended class")

def do_homework(self):

self.homework = Homework(self.name, "math")

class Homework:

def __init__(self, student_name, content):

self.student_name = student_name

self.content = content

if __name__ == "__main__":

teacher = Teacher("Tom")

students = [Student("Alice"), Student("Bob")]

classroom = Classroom(teacher, students)

classroom.attend_class()

classroom.assign_homework()

classroom.submit_homework()

classroom.publish_announcement("Today's class is over")

```

在这个版本中,班级类和学生类之间的耦合度较为严重,班级类需要和学生类直接交互,如调用学生类的 do_class() 和 do_homework() 方法,获取学生类的 homework 属性,这样就破坏了班级类和学生类之间的封装性。如果班级类中有一个新增操作,就需要修改班级类和学生类之间的交互逻辑,非常不稳定。

针对这种情况,可以通过应用迪米特法则来改进代码。具体来说,班级类只需要直接调用讲师类的 check_homework() 和 publish_announcement() 方法,而讲师类的 check_homework() 方法中需要传递一个 Homework 对象作为参数,这个 Homework 对象由学生类生成并自己管理,而不需要班级类介入。这样,班级类和学生类之间的耦合度得到了大大降低,系统可扩展性也得到了提高。

满足迪米特法则的版本:

```python

class Classroom:

def __init__(self, teacher, students):

self.teacher = teacher

self.students = students

def attend_class(self):

for student in self.students:

student.do_class()

def submit_homework(self):

for student in self.students:

self.teacher.check_homework(student.homework)

def publish_announcement(self, announcement):

self.teacher.publish_announcement(announcement)

class Teacher:

def __init__(self, name):

self.name = name

def check_homework(self, homework):

print(f"{self.name} is checking homework of {homework.student_name} ({homework.content})")

def publish_announcement(self, announcement):

print(f"{self.name} published announcement: {announcement}")

class Student:

def __init__(self, name):

self.name = name

self.homework = None

def do_class(self):

print(f"{self.name} attended class")

def do_homework(self):

self.homework = Homework(self.name, "math")

class Homework:

def __init__(self, student_name, content):

self.student_name = student_name

self.content = content

if __name__ == "__main__":

teacher = Teacher("Tom")

students = [Student("Alice"), Student("Bob")]

classroom = Classroom(teacher, students)

classroom.attend_class()

for student in students:

student.do_homework()

classroom.submit_homework()

classroom.publish_announcement("Today's class is over")

```

在这个版本中,班级类的 submit_homework() 方法和 publish_announcement() 方法只调用了讲师类的方法,并没有和学生类直接交互,从而实现了对象之间的解耦。

总结

迪米特法则是一种关注对象之间通信的软件设计原则,它可以帮助我们建立松散耦合的系统,提高系统的可扩展性、降低系统的维护成本。通过遵守迪米特法则,我们可以让对象之间只暴露必要的行为和属性,避免暴露过多细节,从而实现代码的高内聚、低耦合的目标。

壹涵网络我们是一家专注于网站建设、企业营销、网站关键词排名、AI内容生成、新媒体营销和短视频营销等业务的公司。我们拥有一支优秀的团队,专门致力于为客户提供优质的服务。

我们致力于为客户提供一站式的互联网营销服务,帮助客户在激烈的市场竞争中获得更大的优势和发展机会!

点赞(69) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿
发表
评论
返回
顶部