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

Java的迪米特原则介绍

01.问题思考的分析什么是迪米特原则这个原则如何理解如何运用到实际开发举例说明一下什么是高内聚松耦合能否举例说明一下迪米特法则。尽管它不像 SOLID、KISS、DRY 原则那样人尽皆知但它却非常实用。利用这个原则能够帮我们实现代码的“高内聚、松耦合”。今天就围绕下面几个问题并结合两个代码实战案例来深入地学习这个法则。什么是“高内聚、松耦合”如何利用迪米特法则来实现“高内聚、松耦合”有哪些代码设计是明显违背迪米特法则的对此又该如何重构02.学习迪米特原则目标迪米特原则Law of Demeter也被称为最少知识原则Principle of Least Knowledge是面向对象设计中的一个重要原则。能够清晰知道该原则的思想并且可以应用到实际代码中学习的目标是降低类之间的耦合性提高代码的可维护性和可扩展性。03.理解迪米特原则3.1 迪米特原则介绍迪米特法则的英文翻译是Law of Demeter缩写是 LOD。不过它还有另外一个更加达意的名字叫作最小知识原则英文翻译为The Least Knowledge Principle。关于这个设计原则我们先来看一下它最原汁原味的英文定义Each unit should have only limited knowledge about other units: only units “closely” related to the current unit. Or: Each unit should only talk to its friends; Don’t talk to strangers.把它直译成中文 每个模块unit只应该了解那些与它关系密切的模块units: only units “closely” related to the current unit的有限知识knowledge。或者说每个模块只和自己的朋友“说话”talk不和陌生人“说话”talk。3.2 迪米特原则由来类与类之间的关系越密切耦合度越大当一个类发生改变时对另一个类的影响也越大。这个时候要降低类之间耦合3.3 内聚和耦合关系“高内聚”有助于“松耦合”同理“低内聚”也会导致“紧耦合”。类的粒度比较小每个类的职责都比较单一。相近的功能都放到了一个类中不相近的功能被分割到了多个类中。这样类更加独立代码的内聚性更好。因为职责单一所以每个类被依赖的类就会比较少代码低耦合。一个类的修改只会影响到一个依赖类的代码改动。我们只需要测试这一个依赖类是否还能正常工作就行了。类粒度比较大低内聚功能大而全不相近的功能放到了一个类中。这就导致很多其他类都依赖这个类。当我们修改这个类的某一个功能代码的时候会影响依赖它的多个类。这也就是所谓的“牵一发而动全身”。3.3 何为高内聚松耦合“高内聚、松耦合”是一个非常重要的设计思想。能够有效地提高代码的可读性和可维护性缩小功能改动导致的代码改动范围。很多设计原则都以实现代码的“高内聚、松耦合”为目的比如单一职责原则、基于接口而非实现编程等。在这个设计思想中“高内聚”用来指导类本身的设计“松耦合”用来指导类与类之间依赖关系的设计。所谓高内聚就是指相近的功能应该放到同一个类中不相近的功能不要放到同一个类中。相近的功能往往会被同时修改放到同一个类中修改会比较集中代码容易维护。所谓松耦合是说在代码中类与类之间的依赖关系简单清晰。即使两个类有依赖关系一个类的代码改动不会或者很少导致依赖类的代码改动。04.迪米特原则思想迪米特原则的核心观念 : 就是类之间的解耦解耦是有一定程度的尽量做到弱耦合耦合程度越低类的复用率才能提高。由于减少了类之间不必要的依赖从而达到了降低了耦合的目的。迪米特法则的原理是通过封装和信息隐藏来实现对象之间的松耦合。每个对象只需要知道与之直接交互的对象的接口而不需要了解对象的内部实现细节。05.迪米特原则案例1例子有一个集团公司下属单位有分公司和直属部门现在要求打印出所有下属单位的员工ID。先来看一下违反迪米特法则的设计。// 总公司员工 class Employee { private String id; public String getId() { return id; } public void setId(String id) { this.id id; } } // 分公司员工 class SubEmployee { private String id; public String getId() { return id; } public void setId(String id) { this.id id; } } // 子公司管理 class SubCompanyManager { public ListSubEmployee getAllEmployee() { ListSubEmployee list new ArrayList(); for (int i 1; i 5; i) { SubEmployee subEmployee new SubEmployee(); // 给分公司人员顺序分配一个ID subEmployee.setId(分公司 i); list.add(subEmployee); } return list; } } // 总公司管理 class CompanyManager { public ListEmployee getAllEmployee() { ListEmployee list new ArrayList(); for (int i 1; i 3; i) { Employee employee new Employee(); // 给总公司人员顺序分配一个ID employee.setId(总公司 i); list.add(employee); } return list; } public void printAllEmployee(SubCompanyManager subCompanyManager) { // 分公司员工 ListSubEmployee subEmployeeList subCompanyManager.getAllEmployee(); for (SubEmployee subEmployee : subEmployeeList) { System.out.println(subEmployee.getId()); } // 总公司员工 ListEmployee employeeList getAllEmployee(); for (Employee employee : employeeList) { System.out.println(employee.getId()); } } }问题出现在CompanyManager类根据迪米特法则只与直接的朋友发生通信。而SubEmployee类并不是CompanyManager类的直接朋友以局部变量出现的耦合不属于直接朋友从逻辑上讲总公司只与他的分公司耦合就行了与分公司的员工并没有任何联系这样设计显然是增加了不必要的耦合。按照迪米特法则应该避免类中出现这样非直接朋友关系的耦合。修改后的代码如下// 总公司员工 class Employee { private String id; public String getId() { return id; } public void setId(String id) { this.id id; } } // 分公司员工 class SubEmployee { private String id; public String getId() { return id; } public void setId(String id) { this.id id; } } // 子公司管理 class SubCompanyManager { public ListSubEmployee getAllEmployee() { ListSubEmployee list new ArrayList(); for (int i 1; i 5; i) { SubEmployee subEmployee new SubEmployee(); // 给分公司人员顺序分配一个ID subEmployee.setId(分公司 i); list.add(subEmployee); } return list; } public void printSubCompany() { ListSubEmployee subEmployeeList this.getAllEmployee(); for (SubEmployee subEmployee : subEmployeeList) { System.out.println(subEmployee.getId()); } } } // 总公司管理 class CompanyManager { public ListEmployee getAllEmployee() { ListEmployee list new ArrayList(); for (int i 1; i 3; i) { Employee employee new Employee(); // 给总公司人员顺序分配一个ID employee.setId(总公司 i); list.add(employee); } return list; } public void printAllEmployee(SubCompanyManager subCompanyManager) { // 分公司员工 subCompanyManager.printSubCompany(); // 总公司员工 ListEmployee employeeList getAllEmployee(); for (Employee employee : employeeList) { System.out.println(employee.getId()); } } } public class Client { public static void main(String[] args) { CompanyManager companyManager new CompanyManager(); companyManager.printAllEmployee(new SubCompanyManager()); } }修改后为分公司增加了打印人员ID的方法总公司直接调用来打印从而避免了与分公司的员工发生耦合。06.迪米特原则案例2上体育课我们经常有这样一个场景体育老师上课前要体育委员确认一下全班女生到了多少位也就是体育委员清点女生的人数。public class Teacher{ //老师对体育委员发一个命令让其清点女生人数 public void command(GroupLeader groupLeader){ ListGirl listGirls new ArrayList(); //初始化女生 for(int i0;i20;i){ listGirls.add(new Girl()); } //告诉体育委员开始清点女生人数 groupLeader.countGirls(listGirls); } } public class GroupLeader{ //清点女生数量 public void countGirls(ListGirl listGirls){ System.out.println(女生人数是listGirls.size()); } } publci class Girl{ } public class Client{ public static void main(Strings[] args){ Teacher teacher new Teacher(); //老师给体育委员发清点女生人数的命令 teacher.command(new GroupLeader()); } }我们再回头看Teacher类Teacher类只有一个朋友类GroupLeaderGirl类不是朋友类但是Teacher与Girl类通信了这就破坏了Teacher类的健壮性Teacher类的方法竟然与一个不是自己的朋友类Girl类通信这是不允许的严重违反了迪米特原则。public class Teacher{ //老师对体育委员发一个命令让其清点女生人数 public void command(GroupLeader groupLeader){ //告诉体育委员开始清点女生人数 groupLeader.countGirls(); } } public class GroupLeader{ private ListGirl listGirls; public GroupLeader(ListGirl listGirls){ this.listGirls listGirls; } //清点女生数量 public void countGirls(){ System.out.println(女生人数是listGirls.size()); } } public class Client{ public static void main(Strings[] args){ //产生女生群体 ListGirl listGirls new ArrayListGirl(); //初始化女生 for(int i0;i20;i){ listGirls.add(new Girl()); } Teacher teacher new Teacher(); //老师给体育委员发清点女生人数的命令 teacher.command(new GroupLeader(listGirls)); } }对程序修改把Teacher中对Girl群体的初始化移动到场景类中同时在GroupLeader中增加对Girl的注入避开了Teacher类对陌生类Girl的访问降低了系统间的耦合提高了系统的健壮性。07.迪米特原则思考7.1 迪米特原则要点降低耦合性迪米特原则鼓励将关注点分离使得类之间的依赖关系尽可能松散。一个类应该尽量减少对其他类的直接依赖而是通过中间类或接口进行通信。提高模块独立性迪米特原则鼓励将系统划分为独立的模块每个模块只与其直接的朋友直接依赖的类进行通信。使得模块更加独立修改一个模块不会对其他模块造成影响提高了系统的可扩展性和可重用性。保护隐私信息迪米特原则要求一个对象只与其直接的朋友进行通信不要暴露过多的内部信息给外部对象。这样可以保护对象的隐私信息减少不必要的依赖和耦合。提高代码的可维护性通过遵循迪米特原则代码的结构更加清晰类之间的关系更加简单明了。这使得代码更易于理解、调试和修改提高了代码的可维护性。不该有直接依赖关系的类之间不要有依赖有依赖关系的类之间尽量只依赖必要的接口。迪米特法则是希望减少类之间的耦合让类越独立越好。每个类都应该少了解系统的其他部分。一旦发生变化需要了解这一变化的类就会比较少。7.2 迪米特原则优缺点优点降低类之间的耦合度提高了模块的相对独立性耦合度降低从而提高了类的可重用率和系统的扩展性缺点过度使用迪米特原则会产生大量的中介类导致系统的复杂度提高。在釆用迪米特法则时需要反复权衡确保高内聚和低耦合的同时保证系统的结构清晰。7.3 迪米特设计体现广义的迪米特法则在类的设计上的体现优先考虑将一个类设置成不变类。尽量降低一个类的访问权限。谨慎使用Serializable。尽量降低成员的访问权限。7.4 思考迪米特原则场景有几个设计模式在实现中使用了迪米特原则包括通过提供一个简化的接口将复杂子系统的接口与客户端解耦符合迪米特原则的要求使得客户端不需要了解子系统的内部细节。通过引入一个中介者对象将多个对象之间的通信集中处理减少对象之间的直接交互符合迪米特原则的要求。通过提供一个统一的迭代接口隐藏集合对象的内部结构使得客户端不需要了解集合的具体实现细节符合迪米特原则的要求。这些设计模式都通过减少对象之间的直接依赖关系showWEIBO.COM/ttarticle/p/show?id2309405283388197306601降低耦合度提高系统的可维护性和灵活性从而符合迪米特原则的设计原则。

相关文章:

Java的迪米特原则介绍

01.问题思考的分析什么是迪米特原则,这个原则如何理解,如何运用到实际开发,举例说明一下?什么是高内聚松耦合,能否举例说明一下?迪米特法则。尽管它不像 SOLID、KISS、DRY 原则那样,人尽皆知&am…...

glb模型在Cesium中发黑的机理分析

最近在将一款火箭模型(fbx模式)转换为glb(gltf)格式后,在Cesium中加载结果模型看起来全黑,经过分析发现是由于高光的折射率等级(IOR level)默认设置错误(设置为0)导致的,将其设置为0.5即可在Cesium中表现正常。 现象 现有一个fbx格…...

【Epic认证级适配流程】:UE6.5.0–6.5.3全版本C++27支持矩阵,含3大禁用扩展、2个ABI断裂风险点与1份可审计迁移Checklist

第一章:Epic认证级C27适配的合规性基准与目标定义Epic Games官方于2024年Q3发布的《Unreal Engine 5.5 C Language Compliance Framework》首次将C27草案核心特性纳入引擎构建工具链的强制验证范围。本章确立的合规性基准并非仅面向语法兼容,而是聚焦于A…...

关于初次学习的c语言心得

我是一名大一下的学生,双非二本,因为一些原因休学了两年,现在正在努力学习c语言目标成为公司里面所谓的精通编程,学习c语言的过程每天坚持三小时以上,希望能进入像京东,华为等公司,我也想挣钱买…...

Windows驱动存储深度管理:DriverStore Explorer全方位解决方案

Windows驱动存储深度管理:DriverStore Explorer全方位解决方案 【免费下载链接】DriverStoreExplorer Driver Store Explorer 项目地址: https://gitcode.com/gh_mirrors/dr/DriverStoreExplorer 一、驱动管理困境与突破路径 1.1 系统驱动管理的核心挑战 W…...

Youtu-Parsing快速部署指南:一键启动Web服务,5分钟开始解析文档

Youtu-Parsing快速部署指南:一键启动Web服务,5分钟开始解析文档 1. 引言:为什么选择Youtu-Parsing 在日常工作中,我们经常需要处理各种文档——合同、报告、表格、发票等。传统的手动录入方式不仅效率低下,还容易出错…...

3个技巧让你轻松获取Steam创意工坊资源:WorkshopDL的跨平台下载解决方案

3个技巧让你轻松获取Steam创意工坊资源:WorkshopDL的跨平台下载解决方案 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL 在游戏模组爱好者的日常中,总会…...

专业级OBS模糊插件全攻略:obs-composite-blur技术解析与应用指南

专业级OBS模糊插件全攻略:obs-composite-blur技术解析与应用指南 【免费下载链接】obs-composite-blur A comprehensive blur plugin for OBS that provides several different blur algorithms, and proper compositing. 项目地址: https://gitcode.com/gh_mirro…...

ok-wuthering-waves:基于视觉识别的鸣潮智能辅助系统技术解析

ok-wuthering-waves:基于视觉识别的鸣潮智能辅助系统技术解析 【免费下载链接】ok-wuthering-waves 鸣潮 后台自动战斗 自动刷声骸 一键日常 Automation for Wuthering Waves 项目地址: https://gitcode.com/GitHub_Trending/ok/ok-wuthering-waves ok-wuthe…...

Linux 五大 I/O 模型深度解析

在构建高并发、高性能的后端系统时(如各种中间件、Web 服务器),我们不可避免地会接触到 I/O(Input/Output)模型。很多开发者对 BIO、NIO、AIO 以及多路复用等概念感到混淆。要真正从底层掌握这些模型,我们需…...

OpenClaw配置备份指南:千问3.5-27B模型迁移与快速恢复

OpenClaw配置备份指南:千问3.5-27B模型迁移与快速恢复 1. 为什么需要备份OpenClaw配置? 上周我的主力开发机突然硬盘故障,导致所有OpenClaw配置丢失。当时正在运行的3个自动化流程全部中断,最棘手的是那个每天凌晨自动整理技术文…...

用 DeepWiki 线索看 OpenClaw:它到底用到了哪些 AI 技术?

用 DeepWiki 线索看 OpenClaw:它到底用到了哪些 AI 技术? OpenClaw 近来在个人 AI 助手、Agent 框架和本地优先智能体领域里讨论度很高。很多人第一次看到它,会把它简单理解为“一个能接聊天渠道的大模型壳子”。但如果顺着 GitHub 文档以及项…...

CosyVoice语音克隆3步上手:5分钟搭建个人语音合成服务

CosyVoice语音克隆3步上手:5分钟搭建个人语音合成服务 1. 快速了解CosyVoice语音克隆 CosyVoice是由阿里巴巴通义实验室开发的多语言语音生成模型,它最吸引人的功能就是零样本声音克隆——只需要3-10秒的参考音频,就能克隆出相似度极高的合…...

VLA学习笔记——持续更新中

5 VLA - Vision-Language-Action 大模型 Vision-Language-Action(视觉 - 语言 - 动作) 大模型是之后 多模态 AI 以及机器人发展的一个非常重要的方向,有了 VLA 这位大神的加持,机器人可以完成由环境感知到动作应对的智能任务。 欢迎大家star! Paper: O…...

Linux内核驱动开发入门:我是如何给一个虚拟CDC ACM设备写“Hello World”驱动的

Linux内核驱动开发入门:手把手实现虚拟CDC ACM设备驱动 第一次接触Linux内核驱动开发时,面对复杂的代码结构和晦涩的概念,我完全摸不着头脑。直到导师扔给我一个USB转串口设备:"试试看能不能让它在Linux上工作"。经过两…...

Chocolatey 安装 Python 3 时那些你可能不知道的隐藏依赖(附详细日志分析)

Chocolatey 安装 Python 3 时那些你可能不知道的隐藏依赖(附详细日志分析) 当你在 Windows 系统上使用 Chocolatey 安装 Python 3 时,表面上看只是一条简单的命令,但背后却隐藏着一系列复杂的依赖处理过程。这些自动安装的组件往往…...

Jetson Orin Nano系统降级实战:从Ubuntu 22.04回退至20.04的避坑指南

1. 为什么需要从Ubuntu 22.04降级到20.04? 最近很多使用Jetson Orin Nano开发板的开发者都遇到了一个棘手的问题:Ubuntu 22.04的软件生态兼容性。我自己在实际项目中就踩过这个坑,当时为了追求新版本的系统性能,直接安装了Ubuntu …...

NXOpen 遍历部件并对每个部件加属性

NXOpen 遍历部件并对每个部件加属性 // Mandatory UF Includes #include <uf.h> #include <uf_object_types.h> // Internal Includes #include <NXOpen/ListingWindow.hxx> #include <NXOpen/NXMessageBox.hxx> #include <NXOpen/UI.hxx> //…...

Atlas800T A2上部署Qwen2.5-Omni-7B音频模型:从驱动安装到vllm-ascend服务启动的保姆级避坑记录

Atlas800T A2服务器部署Qwen2.5-Omni-7B音频模型全流程实战指南 在昇腾Atlas800T A2服务器上部署多模态大模型Qwen2.5-Omni-7B&#xff0c;对于需要处理音频转文字任务的开发者而言&#xff0c;既是技术挑战也是效率提升的关键一步。本文将带你从零开始&#xff0c;逐步完成从硬…...

NXOpen 方式创建拉伸和预览

//用户代码 #include "ExtrudewithPreview.hpp" #include "NXOpen/Body.hxx" #include "NXOpen/Direction.hxx" #include "NXOpen/DisplayableObject.hxx" #include "NXOpen/DisplayModification.hxx" #include "…...

CSS遮罩艺术:从基础阴影到高级毛玻璃特效实战

1. 从零开始理解CSS遮罩 遮罩效果在前端开发中就像给界面元素戴上了一层"面纱"。想象一下&#xff0c;当你需要突出某个弹窗内容时&#xff0c;背后的页面会变暗——这就是最常见的遮罩应用场景。我们先从最基础的实现方式说起。 基础遮罩的实现通常需要一个覆盖全…...

IQuest-Coder-V1功能实测:一键生成高质量SQL查询脚本

IQuest-Coder-V1功能实测&#xff1a;一键生成高质量SQL查询脚本 在数据驱动的时代&#xff0c;SQL查询脚本的编写是每个数据分析师、后端工程师乃至产品经理的日常。面对复杂的业务逻辑和多表关联&#xff0c;手动编写SQL不仅耗时&#xff0c;还容易出错。有没有一种工具&…...

Nanbeige4.1-3B部署避坑指南:vLLM加载失败排查与llm.log日志分析技巧

Nanbeige4.1-3B部署避坑指南&#xff1a;vLLM加载失败排查与llm.log日志分析技巧 1. 引言&#xff1a;从部署成功到问题排查 当你满怀期待地部署一个像Nanbeige4.1-3B这样的高性能小模型时&#xff0c;最怕看到的就是服务启动失败。特别是使用vLLM这种高效推理框架时&#xf…...

SUNFLOWER MATCH LAB 效果深度评测:对比传统CNN与LSTM的识别性能

SUNFLOWER MATCH LAB 效果深度评测&#xff1a;对比传统CNN与LSTM的识别性能 向日葵的生长过程&#xff0c;就像一部无声的纪录片&#xff0c;每一天的叶片舒展、花盘转动都蕴含着丰富的信息。过去&#xff0c;我们想读懂这部纪录片&#xff0c;要么靠农学专家日复一日的田间观…...

Z-Image Turbo在工业设计中的应用:产品概念图生成

Z-Image Turbo在工业设计中的应用&#xff1a;产品概念图生成 1. 引言 工业设计师的日常工作中&#xff0c;最耗时但又最关键的环节是什么&#xff1f;答案往往是概念图的创作和渲染。传统的工作流程中&#xff0c;设计师需要先手绘草图&#xff0c;然后在专业软件中建模、渲…...

Elsevier Tracker终极指南:3分钟搞定学术论文审稿状态追踪

Elsevier Tracker终极指南&#xff1a;3分钟搞定学术论文审稿状态追踪 【免费下载链接】Elsevier-Tracker 项目地址: https://gitcode.com/gh_mirrors/el/Elsevier-Tracker 还在为Elsevier期刊审稿进度而焦虑吗&#xff1f;每天刷新页面、等待邮件通知的日子终于可以结…...

3大核心优势+4类场景方案:Lenovo Legion Toolkit让游戏本性能释放提升30%

3大核心优势4类场景方案&#xff1a;Lenovo Legion Toolkit让游戏本性能释放提升30% 【免费下载链接】LenovoLegionToolkit Lightweight Lenovo Vantage and Hotkeys replacement for Lenovo Legion laptops. 项目地址: https://gitcode.com/gh_mirrors/le/LenovoLegionToolk…...

突破性QQ音乐加密文件解码工具:qmcdump让音乐自由播放的革新方案

突破性QQ音乐加密文件解码工具&#xff1a;qmcdump让音乐自由播放的革新方案 【免费下载链接】qmcdump 一个简单的QQ音乐解码&#xff08;qmcflac/qmc0/qmc3 转 flac/mp3&#xff09;&#xff0c;仅为个人学习参考用。 项目地址: https://gitcode.com/gh_mirrors/qm/qmcdump …...

千问3.5-2B部署教程(低成本GPU方案):单卡24GB显存跑通开源VL模型实录

千问3.5-2B部署教程&#xff08;低成本GPU方案&#xff09;&#xff1a;单卡24GB显存跑通开源VL模型实录 1. 千问3.5-2B模型介绍 千问3.5-2B是Qwen系列中的小型视觉语言模型(VL)&#xff0c;它能够同时理解图片内容和处理自然语言。这个模型特别适合那些需要在有限硬件资源上…...

libssh2非阻塞模式实战:单线程管理多个SSH连接的高效技巧

libssh2非阻塞模式实战&#xff1a;单线程管理多个SSH连接的高效技巧 在当今分布式系统和自动化运维的浪潮中&#xff0c;SSH协议作为远程管理的黄金标准&#xff0c;其性能瓶颈往往出现在需要同时管理大量连接时。传统多线程方案不仅资源消耗大&#xff0c;还面临线程同步的复…...