当前位置: 首页 > news >正文

Java设计模式:一、六大设计原则-04:迪米特法则

文章目录

  • 一、定义:迪米特法则
  • 二、模拟场景:迪米特法则原则
  • 三、违背方案:迪米特法则原则
    • 3.1 工程结构
    • 3.2 学生、老师、校长类
      • 3.2.1 学生类
      • 3.2.2 老师类
      • 3.2.3 校长类
    • 3.3 单元测试
  • 四、改善代码:迪米特法则原则
    • 4.1 工程结构
    • 4.2 学生、老师、校长类
      • 4.2.1 学生类
      • 4.2.2 老师类
      • 4.2.3 校长类
    • 4.3 单元测试

一、定义:迪米特法则

  • 迪米特法则(最少知道原则)Least Knowledge Principle,LKP
    • 是指一个对象类对于其他对象类来说,知道的越少越好
    • 也就是说,两个类之间不要有过多的耦合关系,保持最少关联性
  • 迪米特法则有一句经典语录:只和朋友通信,不和陌生人说话。也就是说,有内在关联的类要内聚,没有直接关系的类要低耦合。

二、模拟场景:迪米特法则原则

  • 模拟学生、老师、校长之间关系的例子来说明迪米特法则。
  • 老师需要负责具体某一个学生的学习情况,而校长会关心老师所在班级的总体成绩,不会过问具体某一个学生的学习情况。
    • 如果校长想知道一个班级的总分和平均分,是应该找老师要,还是跟每一个学生要再进行统计呢?
    • 显然是应该找具体的班主任老师。

三、违背方案:迪米特法则原则

3.1 工程结构

design-1.4-0
|——src|——main|--java|--com.lino.design|--Principal.java|--Student.java|--Teacher.java|——test|--java|--com.lino.design.test|--ApiTest.java

3.2 学生、老师、校长类

3.2.1 学生类

Student.java

package com.lino.design;/*** @description: 学生*/
public class Student {/*** 姓名*/private String name;/*** 考试排名*/private int rank;/*** 考试分数*/private double grade;public Student() {}public Student(String name, int rank, double grade) {this.name = name;this.rank = rank;this.grade = grade;}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 getGrade() {return grade;}public void setGrade(double grade) {this.grade = grade;}
}
  • 定义一个学生信息类,包括学生姓名、考试排名、总分。

3.2.2 老师类

Teacher.java

package com.lino.design;import java.util.ArrayList;
import java.util.List;/*** @description: 老师*/
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("花花", 10, 589));studentList.add(new Student("豆豆", 54, 356));studentList.add(new Student("秋雅", 23, 439));studentList.add(new Student("皮皮", 2, 665));studentList.add(new Student("蛋蛋", 19, 502));}public static List<Student> getStudentList() {return studentList;}public String getName() {return name;}public String getClazz() {return clazz;}
}
  • 定义老师类,在老师类里初始化学生的信息,以及提供基本的信息获取接口。

3.2.3 校长类

Principal.java

package com.lino.design;import java.util.HashMap;
import java.util.Map;/*** @description: 校长*/
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<>(16);mapObj.put("班级", teacher.getClazz());mapObj.put("老师", teacher.getName());mapObj.put("学生人数", stuCount);mapObj.put("班级总分数", totalScore);mapObj.put("班级平均分", averageScore);return mapObj;}/*** 平均分*/private double clazzAverageScore() {double totalScore = 0;for (Student stu : Teacher.getStudentList()) {totalScore += stu.getGrade();}return totalScore / Teacher.getStudentList().size();}/*** 总分*/private double clazzTotalScore() {double totalScore = 0;for (Student stu : Teacher.getStudentList()) {totalScore += stu.getGrade();}return totalScore;}/*** 总人数*/private int clazzStudentCount() {return Teacher.getStudentList().size();}}
  • 定义校长类,校长管理全局,并在校长类中获取学生人数、总分、平均分等。

3.3 单元测试

ApiTest.java

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

测试结果

13:49:37.477 [main] INFO  com.lino.design.test.ApiTest - 查询结果:{"学生人数":5,"班级平均分":510.2,"班级":"3年1班","老师":"丽华","班级总分数":2551.0}
  • 以上就是通过校长管理所有学生,老师只提供了非常简单的信息。虽然可以查询到结果,但是违背了迪米特法则,因为校长需要了解每个学生的情况。
  • 如果所有班级都让校长类统计,代码就会变得非常臃肿,也不易于维护和扩展。

四、改善代码:迪米特法则原则

4.1 工程结构

design-1.4-1
|——src|——main|--java|--com.lino.design|--Principal.java|--Student.java|--Teacher.java|——test|--java|--com.lino.design.test|--ApiTest.java

4.2 学生、老师、校长类

  • 从以上的实现方式发现,不该让校长直接管理学生,校长应该管理老师,由老师提供相应的学生信息查询服务。
  • 那么,接下来就是把校长要的信息交给老师类去处理。

4.2.1 学生类

Student.java

package com.lino.design;/*** @description: 学生*/
public class Student {/*** 姓名*/private String name;/*** 考试排名*/private int rank;/*** 考试分数*/private double grade;public Student() {}public Student(String name, int rank, double grade) {this.name = name;this.rank = rank;this.grade = grade;}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 getGrade() {return grade;}public void setGrade(double grade) {this.grade = grade;}
}
  • 定义一个学生信息类,包括学生姓名、考试排名、总分。

4.2.2 老师类

Teacher.java

package com.lino.design;import java.util.ArrayList;
import java.util.List;/*** @description: 老师*/
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("花花", 10, 589));studentList.add(new Student("豆豆", 54, 356));studentList.add(new Student("秋雅", 23, 439));studentList.add(new Student("皮皮", 2, 665));studentList.add(new Student("蛋蛋", 19, 502));}/*** 平均分*/public double clazzAverageScore() {double totalScore = 0;for (Student stu : studentList) {totalScore += stu.getGrade();}return totalScore / studentList.size();}/*** 总分*/public double clazzTotalScore() {double totalScore = 0;for (Student stu : studentList) {totalScore += stu.getGrade();}return totalScore;}/*** 总人数*/public int clazzStudentCount() {return studentList.size();}public static List<Student> getStudentList() {return studentList;}public String getName() {return name;}public String getClazz() {return clazz;}
}
  • 在使用迪米特法则后,把原来违背迪米特法则的服务接口交给老师类处理。
  • 这样每一位老师都会提供相应的功能,校长类只需要调用使用即可,而不需要了解每一位学生的分数。

4.2.3 校长类

Principal.java

package com.lino.design;import java.util.HashMap;
import java.util.Map;/*** @description: 校长*/
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<>(16);mapObj.put("班级", teacher.getClazz());mapObj.put("老师", teacher.getName());mapObj.put("学生人数", stuCount);mapObj.put("班级总分数", totalScore);mapObj.put("班级平均分", averageScore);return mapObj;}
}
  • 校长类直接调用老师类的接口,并获取相应的信息。

4.3 单元测试

ApiTest.java

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

测试结果

13:49:37.477 [main] INFO  com.lino.design.test.ApiTest - 查询结果:{"学生人数":5,"班级平均分":510.2,"班级":"3年1班","老师":"丽华","班级总分数":2551.0}

相关文章:

Java设计模式:一、六大设计原则-04:迪米特法则

文章目录 一、定义&#xff1a;迪米特法则二、模拟场景&#xff1a;迪米特法则原则三、违背方案&#xff1a;迪米特法则原则3.1 工程结构3.2 学生、老师、校长类3.2.1 学生类3.2.2 老师类3.2.3 校长类 3.3 单元测试 四、改善代码&#xff1a;迪米特法则原则4.1 工程结构4.2 学生…...

使用docker部署pg数据库

使用 Docker 部署 PostgreSQL 数据库是一种常见的做法&#xff0c;它提供了方便、可移植和可重复的方式来运行数据库。下面是一个简单的示例&#xff0c;用于在 Docker 中部署 PostgreSQL 数据库&#xff1a; 首先&#xff0c;确保您已经安装了 Docker 并正确配置了 Docker 环境…...

Json“牵手”亚马逊商品详情数据方法,亚马逊商品详情API接口,亚马逊API申请指南

亚马逊平台是美国最大的一家网络电子商务公司&#xff0c;亚马逊公司是1995年成立&#xff0c;刚开始只做网上书籍售卖业务&#xff0c;后来扩展到了其他产品。现在已经是全世界商品品种最多的网上零售商和第二互联网公司&#xff0c;亚马逊是北美洲、欧洲等地区的主流购物平台…...

springboot封装查询快递物流

目录 一、ApiClient代码解读二、ApiService代码解读三、HomeController代码解读四、整体代码五、结果展示 一、ApiClient代码解读 这是一个简单的Spring Boot的RestTemplate客户端&#xff0c;用于执行HTTP请求。 首先&#xff0c;这个类被Component注解标记&#xff0c;这意味…...

从C语言到C++_37(特殊类设计和C++类型转换)单例模式

目录 1. 特殊类设计 1.1 不能被拷贝的类 1.2 只能在堆上创建的类 1.3 只能在栈上创建的类 1.4 不能被继承的类 1.5 只能创建一个对象的类(单例模式)(重点) 1.5.1 饿汉模式 1.5.2 懒汉模式 2. 类型转换 2.1 static_cast 2.2 reinterpret_cast 2.3 const_cast 2.4 d…...

go 使用systray 实现托盘和程序退出

1.先 go get 安装 包 go get github.com/getlantern/systray2.使用的代码 func main() {fmt.Println("开始")systray.Run(onReady, onExit) }func onReady() {systray.SetIcon(icon.Data)systray.SetTitle("Awesome App")systray.SetTooltip("Prett…...

Electron之单例+多窗口

Electron之单例多窗口 Electron 24 React 18 单例可以通过app.requestSingleInstanceLock实现&#xff0c;多窗口可以简单通过路由来实现 单例 const gotTheLock app.requestSingleInstanceLock(); if (!gotTheLock) {app.quit(); } else {app.on(second-instance, (event, …...

A Survey of Knowledge-Enhanced Pre-trained Language Models

本文是LLM系列的文章&#xff0c;针对《A Survey of Knowledge-Enhanced Pre-trained Language Models》的翻译。 知识增强的预训练语言模型综述 摘要1 引言2 背景3 KE-PLMs用于NLU4 KE-PLMs用于NLG5 未来的方向5.1 整合来自同质和异质来源的知识5.2 探索多模态知识5.3 提供可…...

动态规划(选择)

链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 来源&#xff1a;牛客网 作为队伍的核心&#xff0c;forever97很受另外两个队友的尊敬。 Trote_w每天都要请forever97吃外卖&#xff0c;但很不幸的是宇宙中心forever97所在的学校周围只有3家forever97爱吃的外卖。 如果T…...

IIS WebDAV配置,https绑定及asp设置

IIS支持标准CGI&#xff0c;因此可以用程序语言针对STDIN和STDOUT开发。 IIS CGI配置和CGI程序FreeBasic, VB6, VC 简单样例_Mongnewer的博客-CSDN博客 IIS支持脚本解释CGI&#xff0c;因此可以用脚本语言针对STDIN和STDOUT开发。 IIS perl python cbrother php脚本语言配置…...

【计算机视觉项目实战】中文场景识别

✨专栏介绍&#xff1a; 经过几个月的精心筹备&#xff0c;本作者推出全新系列《深入浅出OCR》专栏&#xff0c;对标最全OCR教程&#xff0c;具体章节如导图所示&#xff0c;将分别从OCR技术发展、方向、概念、算法、论文、数据集等各种角度展开详细介绍。 &#x1f468;‍&…...

Java 中 Map 初始化的几种方法

# 传统方式 Map<String, String> map new HashMap<>(); map.put("k1", "v1"); map.put("k2", "v2");# java8新特性-双括号初始化 Map<String, String> map1 new HashMap<>() {{put("k1", "v…...

【学习方法论】学习的三种境界、三种习惯、三个要点,三个心态

学习的三种境界、三种习惯、三个要点&#xff0c;三个心态 三种学习境界 苦学 古人云&#xff1a;“头悬梁、锥刺股”&#xff0c;勤学苦练是第一境界。处于这种层次的同学&#xff0c;觉得学习枯燥无味&#xff0c;对他们来说学习是一种被迫行为&#xff0c;体会不到学习中的…...

[管理与领导-67]:IT基层管理者 - 辅助技能 - 4- 职业发展规划 - 评估你与公司的八字是否相合

目录 前言&#xff1a; 一、概述 二、八字相合的步骤 2.1 企业文化是否相合 2.2.1 企业文化对职业选择的意义 2.2.2 个人与企业三观不合的结果 2.2.3 什么样的企业文化的公司不能加入 2.2 公司的发展前景 2.3 公司所处行业发展 2.4 创始人的三观 2.5 创始人与上司的…...

【PMO项目管理】深入了解项目管理 | Stakeholder 利益相关者 | 利益相关者之间的立场差异

&#x1f4ad; 写在前面&#xff1a;本文将带您深入了解项目管理的核心概念和关键要素。我们将从项目管理的基本理解开始&#xff0c;逐步探讨其领域、复杂性和变化的重点&#xff0c;以及项目管理的具体过程。我们还将研究项目的性质以及成功项目所必备的条件。在此过程中&…...

设计模式-原则篇-01.开闭原则

简介 ​ 可以把设计模式理解为一套比较成熟并且成体系的建筑图纸&#xff0c;经过多次编码检验目前看来使用效果还不错的软件设计方案。适用的场景也比较广泛&#xff0c;在使用具体的设计模式之前先要学习软件设计的基础 “软件设计原则”&#xff0c;后面的23个设计模式都是…...

JAVA毕业设计096—基于Java+Springboot+Vue的在线教育系统(源码+数据库+18000字论文)

基于JavaSpringbootVue的在线教育系统(源码数据库18000字论文)096 一、系统介绍 本系统前后端分离 本系统分为管理员、用户两种角色(管理员角色权限可自行分配) 用户功能&#xff1a; 注册、登录、课程预告、在线课程观看、学习资料下载、学习文章预览、个人信息管理、消息…...

windows环境搭建ELK

目录 资源下载&#xff08;8.9.1&#xff09; ES安装、注册、使用 Kibana安装、注册、使用 Logstash安装、注册、使用 Filebeat安装、使用&#xff08;如果只有一个数据流&#xff0c;则不需要使用filebeat&#xff0c;直接上logstash即可&#xff09; 资源下载&#xff0…...

langchain介绍之-Prompt

LangChain 是一个基于语言模型开发应用程序的框架。它使得应用程序具备以下特点&#xff1a;1.数据感知&#xff1a;将语言模型与其他数据源连接起来。2.代理性&#xff1a;允许语言模型与其环境进行交互 LangChain 的主要价值在于&#xff1a;组件&#xff1a;用于处理语言模型…...

汇编语言Nasmide编辑软件

用来编写汇编语言源程序&#xff0c;Windows 记事本并不是一个好工具。同时&#xff0c;在命令行编译源程序也令很多人迷糊。毕竟&#xff0c;很多年轻的朋友都是用着 Windows 成长起来的&#xff0c;他们缺少在 DOS和 UNIX 下工作的经历。 我一直想找一个自己中意的汇编语言编…...

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

el-switch文字内置

el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

Java 加密常用的各种算法及其选择

在数字化时代&#xff0c;数据安全至关重要&#xff0c;Java 作为广泛应用的编程语言&#xff0c;提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景&#xff0c;有助于开发者在不同的业务需求中做出正确的选择。​ 一、对称加密算法…...

基于Docker Compose部署Java微服务项目

一. 创建根项目 根项目&#xff08;父项目&#xff09;主要用于依赖管理 一些需要注意的点&#xff1a; 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件&#xff0c;否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...