设计模式原则——迪米特法则原则

设计模式原则

设计模式示例代码库地址:

https://gitee.com/Jasonpupil/designPatterns

迪米特法则原则:

  • 意义在于降低类之间的耦合。由于每个对象尽量减少对于其他对象的了解,因此,很容易使得系统的功能模块功能独立,相互之间不存在(或很少有)依赖关系
  • 迪米特法则还有一个英文解释是:talk only to your immediate friends(只和直接的朋友交流)
  • 什么是朋友:每个对象基本上会与其他的对象有耦合关系,当两个对象之间耦合就会成为朋友关系
  • 什么是直接朋友:出现在成员变量 、局部变量 、全局变量 和方法的输入输出参数中的类就是直接的朋友

模式场景:学生成绩&排名

  • 迪米特法则替换前:教师管理班级里的学生,校长通过教师获取班里的学生来统计出班级的总分、平均分和班级人数
  • 迪米特法则替换后:教师管理班级里的学生,统计出班级的总分、平均分和班级人数由教师来做,校长只需要根据班级寻找老师获取相应的信息

迪米特法则替换前示例代码:

校长类:
java 复制代码
/**
 * @Description: 校长
 * @Author: pupil
 * @Date: 2024/06/24 下午 1:13
 */
public class Principal {

    private Teacher teacher = new Teacher("智盛", "3年1班");

    // 查询班级信息,总分数、学生人数、平均值
    public Map<String, Object> queryClazzInfo(String clazzId) {
        // 获取班级信息;学生总人数、总分、平均分
        int stuCount = clazzStudentCount();
        double totalScore = clazzTotalScore();
        double averageScore = clazzAverageScore();

        // 组装对象,实际业务开发会有对应的类
        Map<String, Object> mapObj = new HashMap<>();
        mapObj.put("班级", teacher.getClazz());
        mapObj.put("老师", teacher.getName());
        mapObj.put("学生人数", stuCount);
        mapObj.put("班级总分数", totalScore);
        mapObj.put("班级平均分", averageScore);
        return mapObj;
    }


    // 总分
    public double clazzTotalScore() {
        double totalScore = 0;
        for (Student stu : teacher.getStudents()) {
            totalScore += stu.getScore();
        }
        return totalScore;
    }

    // 平均分
    public double clazzAverageScore(){
        double totalScore = 0;
        for (Student stu : teacher.getStudents()) {
            totalScore += stu.getScore();
        }
        return totalScore / teacher.getStudents().size();
    }

    // 班级人数
    public int clazzStudentCount(){
        return teacher.getStudents().size();
    }

}
老师类:
java 复制代码
/**
 * @Description: 教师
 * @Author: pupil
 * @Date: 2024/06/24 下午 1:14
 */
public class Teacher {

    private String name;    // 学生姓名
    private String clazz;   // 班级
    private static List<Student> students;  // 学生

    public Teacher() {
    }

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

    static {
        students = new ArrayList<>();
        students.add(new Student("王五", 10, 589));
        students.add(new Student("李四", 100, 256));
        students.add(new Student("小三", 23, 449));
        students.add(new Student("皮皮", 2, 665));
        students.add(new Student("蛋蛋", 15, 532));
    }


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getClazz() {
        return clazz;
    }

    public void setClazz(String clazz) {
        this.clazz = clazz;
    }

    public static List<Student> getStudents() {
        return students;
    }

    public static void setStudents(List<Student> students) {
        Teacher.students = students;
    }
}
学生类:
java 复制代码
/**
 * @Description: 学生
 * @Author: pupil
 * @Date: 2024/06/24 下午 1:14
 */
public class Student {

    private String name;    // 学生姓名
    private int rank;       // 考试排名(总排名)
    private double score;   // 考试分数(总分)

    public Student() {
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getRank() {
        return rank;
    }

    public void setRank(int rank) {
        this.rank = rank;
    }

    public double getScore() {
        return score;
    }

    public void setScore(double score) {
        this.score = score;
    }
}
测试类:
java 复制代码
/**
 * @Description: 测试验证
 * @Author: pupil
 * @Date: 2024/06/24 下午 3:09
 */
public class ApiTest {

    private Logger logger = LoggerFactory.getLogger(ApiTest.class);

    @Test
    public void test_Principal(){
        Principal principal = new Principal();
        Map<String, Object> map = principal.queryClazzInfo("3年1班");
        logger.info("查询结果:{}", JSON.toJSONString(map));
    }
}
结果:

迪米特法则替换后示例代码:

校长类:
java 复制代码
/**
 * @Description: 校长
 * @Author: pupil
 * @Date: 2024/06/24 下午 1:13
 */
public class Principal {

    private Teacher teacher = new Teacher("智盛", "3年1班");

    // 查询班级信息,总分数、学生人数、平均值
    public Map<String, Object> queryClazzInfo(String clazzId) {
        // 获取班级信息;学生总人数、总分、平均分
        int stuCount = teacher.clazzStudentCount();
        double totalScore = teacher.clazzTotalScore();
        double averageScore = teacher.clazzAverageScore();

        // 组装对象,实际业务开发会有对应的类
        Map<String, Object> mapObj = new HashMap<>();
        mapObj.put("班级", teacher.getClazz());
        mapObj.put("老师", teacher.getName());
        mapObj.put("学生人数", stuCount);
        mapObj.put("班级总分数", totalScore);
        mapObj.put("班级平均分", averageScore);
        return mapObj;
    }
}
老师类:
java 复制代码
/**
 * @Description: 教师
 * @Author: pupil
 * @Date: 2024/06/24 下午 1:14
 */
public class Teacher {

    private String name;    // 学生姓名
    private String clazz;   // 班级
    private static List<Student> students;  // 学生

    public Teacher() {
    }

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

    static {
        students = new ArrayList<>();
        students.add(new Student("王五", 10, 589));
        students.add(new Student("李四", 100, 256));
        students.add(new Student("小三", 23, 449));
        students.add(new Student("皮皮", 2, 665));
        students.add(new Student("蛋蛋", 15, 532));
    }

    // 总分
    public double clazzTotalScore() {
        double totalScore = 0;
        for (Student stu : getStudents()) {
            totalScore += stu.getScore();
        }
        return totalScore;
    }

    // 平均分
    public double clazzAverageScore(){
        double totalScore = 0;
        for (Student stu : getStudents()) {
            totalScore += stu.getScore();
        }
        return totalScore / getStudents().size();
    }

    // 班级人数
    public int clazzStudentCount(){
        return getStudents().size();
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getClazz() {
        return clazz;
    }

    public void setClazz(String clazz) {
        this.clazz = clazz;
    }

    public static List<Student> getStudents() {
        return students;
    }

    public static void setStudents(List<Student> students) {
        Teacher.students = students;
    }
}
学生类:
java 复制代码
/**
 * @Description: 学生
 * @Author: pupil
 * @Date: 2024/06/24 下午 1:14
 */
public class Student {

    private String name;    // 学生姓名
    private int rank;       // 考试排名(总排名)
    private double score;   // 考试分数(总分)

    public Student() {
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getRank() {
        return rank;
    }

    public void setRank(int rank) {
        this.rank = rank;
    }

    public double getScore() {
        return score;
    }

    public void setScore(double score) {
        this.score = score;
    }
}
测试类:
java 复制代码
/**
 * @Description: 测试验证
 * @Author: pupil
 * @Date: 2024/06/24 下午 3:09
 */
public class ApiTest {

    private Logger logger = LoggerFactory.getLogger(ApiTest.class);

    @Test
    public void test_Principal(){
        Principal principal = new Principal();
        Map<String, Object> map = principal.queryClazzInfo("3年1班");
        logger.info("查询结果:{}", JSON.toJSONString(map));
    }
}
结果:

根据迪米特法则原则的示例类图:


校长类与教师类是聚合关系

教师类与学生类是聚合关系

相关推荐
旺仔Sec1 小时前
2026年江西省职业院校技能大赛(中职组)应用软件系统开发赛项竞赛样题
java·应用软件系统开发
Dovis(誓平步青云)1 小时前
几个方案来回选不定?做一个随时切换的候选推荐页
android·java·服务器·开发语言·javascript·数据库·智能化
一条破秋裤2 小时前
Linux 线程同步:读写锁
java·linux·jvm
蜗牛互联网2 小时前
从Barclays扩大Claude部署看受监管软件工程的责任重分配
java·大数据·人工智能·后端·软件工程
天远API2 小时前
零信任架构实战:基于天远股权穿透构建自动化供应链授信穿透网关
java·人工智能·架构·自动化
最强小杰2 小时前
claude-opus-5.5 API 接入教程:anthropic-version 头、tools 定义、流式事件格式三个常见问题全部梳理,收藏备用
java·服务器·网络·ai
Cc.Y2 小时前
Java零基础入门:方法(函数)深度掌握
java·开发语言
奋发向前wcx3 小时前
CSP-J复赛模拟赛1 王晨旭补题 2026.10.2
java·开发语言
卓怡学长3 小时前
w192基于springboot“考研情报站”微信小程序设计与实现
java·spring boot·spring·微信小程序·intellij-idea
wuminyu3 小时前
JEP491中synchronized关键字引发的平台线程钉住解决方法简介
java·linux·c语言·jvm·c++