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}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/70623.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

react脚手架初始化项目及ts的应用(react+ts)

1. 安装react脚手架 npm install -g create-react-app 或是 yarn add -g create-react-app2. 初始化项目 快速构建出项目名为my-app的react+ts项目 create-react-app my-app --template typescript3. 配置路径别名 在引入文件时如果都是…/ …/…/这种相对路径方式引用可读性…

vue-cli3项目本地启用https,并用mkcert生成证书

在项目根目录下的vue.config.js文件中&#xff1a; // vue.config.js module.exports {devServer: {host:dev.nm.cngc// 此处开启 https,并加载本地证书&#xff08;否则浏览器左上角会提示不安全&#xff09;https: {cert: fs.readFileSync(path.join(_dirname,./cert.crt)…

【docker】运行redis

拉取redis镜像 有多种选择&#xff1a; redis&#xff08;基础版&#xff09;redis/redis-stack&#xff08;包含redis stack server和RedisInsight&#xff09;redis/redis-stack-server&#xff08;仅包含redis stack server&#xff09; docker pull redis docker pull r…

Python Qt学习(十)一个简易的POP3邮件客户端

公司把126这类的邮箱网站都封了&#xff0c;正好现在无事&#xff0c;加之&#xff0c;算是一个对这俩周学习Qt的一个总结吧。遂写了这么一个简易的通过POP3协议接收126邮件的客户端。 源代码&#xff1a; # -*- coding: utf-8 -*-# Form implementation generated from read…

创建2个线程并执行(STL/Windows/Linux)

C并发编程入门 目录 STL 写法 #include <thread> #include <iostream> using namespace std;void thread_fun1(void) {cout << "one STL thread 1!" << endl; }void thread_fun2(void) {cout << "one STL thread 2!" <…

uni-app之android离线自定义基座

一 为什么要自定义基座 1&#xff0c;基座其实就是一个app&#xff0c;然后新开发的页面可以直接在手机上面显示&#xff0c;查看效果。 2&#xff0c;默认的基座就是uniapp帮我们打包好的基座app&#xff0c;然后我们可以进行页面的调试。 3&#xff0c;自定义基座主要用来…

【Java SE】抽象类与接口

目录 【1】抽象类 【1.1】抽象类概念 【1.2】抽象类语法 【1.3】抽象类特性 【1.4】抽象类的作用 【2】接口 【2.1】接口的概念 【2.2】语法规则 【2.3】接口使用 【2.4】接口特性 【2.5】实现多个接口 【2.6】接口间的继承 【2.7】接口使用实例 【2.8】Clonable …

SVPWM的原理及法则推导和控制算法详解

空间电压矢量调制 SVPWM 技术 SVPWM是近年发展的一种比较新颖的控制方法&#xff0c;是由三相功率逆变器的六个功率开关元件组成的特定开关模式产生的脉宽调制波&#xff0c;能够使输出电流波形尽 可能接近于理想的正弦波形。空间电压矢量PWM与传统的正弦PWM不同&#xff0c;它…

通讯软件017——分分钟学会Kepware OPC UA Server配置

本文介绍如何配置Kepware OPC UA Server&#xff0c;通过本文可以对OPC UA的基本概念有所了解&#xff0c;掌握OPC UA的本质。更多通信资源请登录网信智汇(wangxinzhihui.com)。 1. 创建OPC UA Server 点击“OPC UA Configuration”&#xff0c;弹出配置界面。 点击“添加”&a…

vue开启屏幕录制

在不使用https的时候&#xff0c;只能localhost使用&#xff0c;保护机制 一、导入依赖 npm install vue-webrtc --save2、使用 <template><div><button click"startRecording">开始录制</button><button click"stopRecording&quo…

数据结构 > 什么是数据结构?

目录 1.什么是数据结构&#xff1f; 2.什么是算法&#xff1f; 3.数据结构和算法的重要性 4.如何学好数据结构和算法 5.总结 很多时候我们都叫数据结构和算法 1.什么是数据结构&#xff1f; 数据结构(Data Stricture)是计算机存储、组织数据的方式&#xff0c;指相互之间…

java八股文面试[数据库]——explain

使用 EXPLAIN 关键字可以模拟优化器来执行SQL查询语句&#xff0c;从而知道MySQL是如何处理我们的SQL语句的。分析出查询语句或是表结构的性能瓶颈。 MySQL查询过程 通过explain我们可以获得以下信息&#xff1a; 表的读取顺序 数据读取操作的操作类型 哪些索引可以被使用 …

正中优配:政策预期叠加资金面压制 债市回调至“降息”前

地产方针利好和资金面边沿收紧的压制之下&#xff0c;债券商场出现了回调。 到9月6日收盘&#xff0c;10年期国债收益率上行2.4个基点报2.665%&#xff0c;已回到降息之前的点位。 资金面也在收敛&#xff0c;到6日收盘&#xff0c;DR001加权均匀利率报1.51%&#xff0c;较前…

一文讲解Linux内核内存管理架构

内存管理子系统可能是linux内核中最为复杂的一个子系统&#xff0c;其支持的功能需求众多&#xff0c;如页面映射、页面分配、页面回收、页面交换、冷热页面、紧急页面、页面碎片管理、页面缓存、页面统计等&#xff0c;而且对性能也有很高的要求。本文从内存管理硬件架构、地址…

mac制作ssl证书|生成自签名证书,nodejs+express在mac上搭建https+wss(websocket)服务器

注意 mac 自带 openssl 所以没必要像 windows 一样先安装 openssl&#xff0c;直接生成即可 生成 ssl/自签名 证书 生成 key # 生成rsa私钥&#xff0c;des3算法&#xff0c;server_ssl.key是秘钥文件名 1024位强度 openssl genrsa -des3 -out server_ssl.key 1024让输入两…

【前端】Vue2 脚手架模块化开发 -快速入门

&#x1f384;欢迎来到边境矢梦的csdn博文&#x1f384; &#x1f384;本文主要梳理Vue2 脚手架模块化开发 &#x1f384; &#x1f308;我是边境矢梦&#xff0c;一个正在为秋招和算法竞赛做准备的学生&#x1f308; &#x1f386;喜欢的朋友可以关注一下&#x1faf0;&#x…

iOS逆向进阶:iOS进程间通信方案深入探究与local socket介绍

在移动应用开发中&#xff0c;进程间通信&#xff08;Inter-Process Communication&#xff0c;IPC&#xff09;是一项至关重要的技术&#xff0c;用于不同应用之间的协作和数据共享。在iOS生态系统中&#xff0c;进程和线程是基本的概念&#xff0c;而进程间通信方案则为应用的…

数据结构--字典树(trie)

概念&#xff1a; Trie 是一种能够快速插入和查询字符串的多叉树结构。、 节点的编号各不相同&#xff0c;根节点编号为0&#xff0c;其他节点用来标识路径&#xff0c;还可以标记单词的插入次数&#xff0c;边表示字符。 tire 维护字符串的集合&#xff0c;支持两种操作&…

40个Linux常用命令组合

1.删除0字节文件 find -type f -size 0 -exec rm -rf {} \; 2.查看进程 按内存从大到小排列 ps -e -o "%C : %p : %z : %a"|sort -k5 -nr 3.按cpu利用率从大到小排列 ps -e -o "%C : %p : %z : %a"|sort -nr 4.打印说cache里的URL grep -r -a jpg …

accelerate 分布式技巧(一)

accelerate分布式技巧 简单使用 Accelerate是一个来自Hugging Face的库&#xff0c;它简化了将单个GPU的PyTorch代码转换为单个或多台机器上的多个GPU的代码。 Accelerate精确地抽象了与多GPU/TPU/fp16相关的模板代码&#xff0c;并保持Pytorch其余代码不变。 import torchim…