python 设计模式(二) 六大设计原则五 迪米特原则(Law of Demeter)

迪米特原则又称最少知识原则(least knowledge principle)简称LKP。意思是说一个对象应该对其他对象有尽可能少的了解。本篇播客参照了迪米特原则的百度百科,以及这篇播客 六大设计原则之迪米特原则。thanks  a  lot。

迪米特原则的一个解释是(talk only to your immediate friends)。只与直接朋友对话。什么是直接朋友呢。两个类有耦合就是朋友关系。直接朋友,我的理解是类之间是通过参数调用产生关系的,而不是直接内嵌的。下面的代码会进行解释:

例子同样来自 六大设计原则之迪米特原则这篇博客。

1 不遵从迪米特原则的例子

体育课上,体育老师要进行点名,她让体育课代表去点名。类Teacher与类 StudentList, Student, Representative都有耦合关系,但他们都是内嵌到类Teacher的command方法中。这就不符合迪米特原则了。代码如下


class Teacher(object):

    def __init__(self):
        pass

    def command(self):
        print('体育老师让课代表点名')
        studentlist = StudentList()
        for _ in range(20):
            studentlist.append(Student())
        print('课代表开始点名')
        representative = Representative()
        representative.count(studentlist)


class Student(object):
    pass


class StudentList(list):
    pass


class Representative(object):

    def count(self, studentlist):
        print('课代表已经点完名,共有人数%d' % len(studentlist))


class Client(object):

    def main(self, teacher):
        teacher.command()

if __name__ == '__main__':
    client = Client()
    teacher = Teacher()
    client.main(teacher)

结果如下

体育老师让课代表点名
课代表开始点名
课代表已经点完名,共有人数20

2 把上面的代码修改为符合迪米特原则

从上面的代码可知,teacher的下级是representative,其应该只与representative是直接朋友关系。representative也应该只与studentlist是直接朋友关系。因此代码可以修改为这样:


class Teacher(object):

    def __init__(self, representative):
        self.representative = representative

    def command(self):
        print('老师让课代表点名')
        self.representative.count()


class Representative(object):

    def __init__(self, studentlist):
        self.studentlist = studentlist

    def count(self):
        print('课代表开始点名')
        self.studentlist.size()


class StudentList(list):

    def add_student(self, num):
        for _ in range(num):
            self.append(Student())

    def size(self):
        print('学生的人数为%s' % str(len(self)))


class Student(object):
    pass


class Client(object):
    def main(self, teacher):
        teacher.command()

if __name__ == '__main__':
    studentlist = StudentList()
    studentlist.add_student(10)
    representative = Representative(studentlist)
    teacher = Teacher(representative)
    client = Client()
    client.main(teacher)

结果如下

老师让课代表点名
课代表开始点名
学生的人数为10

从修改后的代码可以看出,teacher,representative,studentlist是层级关系,这种关系也可以以内嵌的形式都写进teacher的command方法中,也可以像修改后的代码一样,采用逐级传递参数的方式来反映层级关系。

猜你喜欢

转载自blog.csdn.net/ruguowoshiyu/article/details/81269908