搞定设计模式之迪米特法则一篇文章就够了!!!

Posted 南淮北安

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了搞定设计模式之迪米特法则一篇文章就够了!!!相关的知识,希望对你有一定的参考价值。

一、定义

迪米特法则(Law of Demeter,LoD)又称为最少知道原则(LeastKnowledge Principle,LKP),是指一个对象类对于其他对象类来说,知道得越少越好。

也就是说,两个类之间不要有过多的耦合关系,保持最少关联性。

迪米特法则有一句经典语录:只和朋友通信,不和陌生人说话。

也就是说,有内在关联的类要内聚,没有直接关系的类要低耦合。

这样的例子在我们生活中也随处可见,就像家里的水管装修,有洗衣机地漏、卫生间地漏、厨房地漏,但它们最终都汇到同一个污水处理系统里。

在平常使用时,我们不会考虑这些水管是怎么关联流向的,只需要考虑最上层的使用即可。

二、示例问题

老师需要负责具体某一个学生的学习情况,而校长会关心老师所在班级的总体成绩,不会过问具体某一个学生的学习情况。

如果校长想知道一个班级的总分和平均分,是应该找老师要,还是跟每一个学生要再进行统计呢?显然是应该找具体的班主任老师。我们在实际开发时,容易忽略这样的真实情况,开发出逻辑错误的程序。

首先定义一个学生信息类,这个类比较简单,包括学生姓名、考试排名、总分。在实际的业务开发中会更复杂,这里只是简化后的类。

@Data
public class Student {
    // 姓名
    private String name;
    // 排名
    private int rank;
    // 总分
    private double grade;

    public Student(String name, int rank, double grade) {
        this.name = name;
        this.rank = rank;
        this.grade = grade;
    }
}

之后再定义出老师类,在老师类里初始化学生的信息,以及提供基本的信息获取接口。

public class Teacher {
    private String name;
    private String clazz;
    private static List<Student> studentList;

    public Teacher() {
    }

    public Teacher(String name, String clazz) {
        this.name = name;
        this.clazz = clazz;
    }

    static {
        studentList = new ArrayList<>();
        studentList.add(new Student("s1", 10, 345));
        studentList.add(new Student("s2", 20, 245));
        studentList.add(new Student("s3", 30, 145));
        studentList.add(new Student("s4", 40, 45));
    }

    public List<Student> getStudentList() {
        return studentList;
    }

    public String getName() {
        return name;
    }

    public String getClazz() {
        return clazz;
    }
}

在老师类中初始化了学生信息,同时提供了简单的接口。接下来定义校长类,校长管理全局,并在校长类中获取学生人数、总分、平均分等。

public class Principal {
    private Teacher teacher = new Teacher("t1", "1年级1班");

    public Map<String, Object> queryClazzInfo(String clazzId) {
        Map<String, Object> map = new HashMap<>();
        map.put("班级", teacher.getClazz());
        map.put("老师姓名", teacher.getName());
        map.put("总分", totalScore());
        return map;
    }

    public double totalScore() {
        double totalScore = 0;
        for (Student stu : teacher.getStudentList()) {
            totalScore += stu.getGrade();
        }
        return totalScore;
    }
}

以上就是通过校长管理所有学生,老师只提供了非常简单的信息。

虽然可以查询到结果,但是违背了迪米特法则,因为校长需要了解每个学生的情况。如果所有班级都让校长类统计,代码就会变得非常臃肿,也不易于维护和扩展

三、问题改进

从以上的实现方式我们发现,不该让校长直接管理学生,校长应该管理老师,由老师提供相应的学生信息查询服务。

那么,接下来我们就把校长要的信息交给老师类去处理。

在使用迪米特法则后,把原来违背迪米特法则的服务接口交给老师类处理。

这样每一位老师都会提供相应的功能,校长类只需要调用使用即可,而不需要了解每一位学生的分数。


校长类直接调用老师类的接口,并获取相应的信息。

这样一来,整个功能逻辑就非常清晰了。

以上是关于搞定设计模式之迪米特法则一篇文章就够了!!!的主要内容,如果未能解决你的问题,请参考以下文章

搞定设计模式之工厂模式一篇文章就够了!!!

搞定设计模式之接口隔离原则一篇文章就够了!!!

搞定里式替换原则的设计模式一篇文章就够了!!!

搞定单一职责的设计模式一篇文章就够了!!!

搞定开闭原则的设计模式一篇文章就够了!!!

搞定 WeakHashMap 的工作原理一篇文章就够了!!!