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

迪米特原则的理解和实践

        迪米特原则(Law of Demeter,简称LoD),也被称为最少知识原则(Least Knowledge Principle,LKP),是面向对象设计中的一个重要原则。其核心思想是:一个对象应该对其他对象有最少的了解,即一个对象应该尽可能少地了解其直接对象之外的任何对象。本文将详细探讨迪米特原则的理论理解及其在Java实践中的应用。

一、迪米特原则的理论理解

        迪米特原则的核心在于降低类之间的耦合度,提高模块的相对独立性。通过封装和信息隐藏,对象之间的通信应该通过抽象层进行,以减少对象之间的直接依赖。这种设计方式能够提高系统的可维护性和可扩展性,降低代码的依赖性,减少系统中的风险因素。

  1. 降低耦合度
    耦合度是指不同模块之间相互依赖的程度。过高的耦合度会导致代码难以维护和扩展。迪米特原则通过限制对象之间的直接通信,促使开发者使用接口或中间层来进行通信,从而有效地降低系统各部分之间的耦合度。

  2. 提高内聚力
    内聚力是指模块内部各元素间的紧密程度。高内聚力的模块功能更加专一,易于理解和修改。迪米特原则通过限制对象间的直接交流,促使开发者将功能相似的代码组织在一起,提高了模块的内聚力。

  3. 便于测试和重用
    通过遵循迪米特原则,每个类的功能更加单一和明确,这有助于对单个功能进行独立的测试,从而提高代码的可测试性。同时,减少类之间的直接依赖关系,使得类更加容易重用。

  4. 增强系统的可扩展性
    通过降低类之间的耦合,迪米特原则使得系统的某个部分在不改变其他部分的情况下可以进行修改或扩展,从而增强了系统的可扩展性。

二、迪米特原则的实践

        在Java开发中,迪米特原则可以通过多种方式来实现,包括中介者模式、控制反转(IoC)和依赖注入(DI)、事件驱动编程以及模块化设计等。下面通过具体的代码示例来展示迪米特原则的实践。

示例一:中介者模式

        当一个类需要与多个类进行交互时,可以使用中介者模式来降低类之间的直接依赖。中介者负责协调各个类之间的交互,从而减少类之间的直接通信。

// 中介者接口
interface Mediator {void send(String message, String colleagueName);
}// 具体中介者类
class ConcreteMediator implements Mediator {private ColleagueA colleagueA;private ColleagueB colleagueB;public void setColleagueA(ColleagueA colleagueA) {this.colleagueA = colleagueA;}public void setColleagueB(ColleagueB colleagueB) {this.colleagueB = colleagueB;}@Overridepublic void send(String message, String colleagueName) {if ("A".equals(colleagueName)) {colleagueA.receive(message);} else if ("B".equals(colleagueName)) {colleagueB.receive(message);}}
}// 同事类A
class ColleagueA {private Mediator mediator;public void setMediator(Mediator mediator) {this.mediator = mediator;}public void send(String message) {mediator.send(message, "B");}public void receive(String message) {System.out.println("ColleagueA received: " + message);}
}// 同事类B
class ColleagueB {private Mediator mediator;public void setMediator(Mediator mediator) {this.mediator = mediator;}public void send(String message) {mediator.send(message, "A");}public void receive(String message) {System.out.println("ColleagueB received: " + message);}
}// 测试类
public class MediatorPatternDemo {public static void main(String[] args) {Mediator mediator = new ConcreteMediator();ColleagueA colleagueA = new ColleagueA();ColleagueB colleagueB = new ColleagueB();mediator.setColleagueA(colleagueA);mediator.setColleagueB(colleagueB);colleagueA.setMediator(mediator);colleagueB.setMediator(mediator);colleagueA.send("Hello B");colleagueB.send("Hello A");}
}

        在这个示例中,ColleagueA 和 ColleagueB 通过 Mediator 进行通信,而不是直接调用对方的方法。这降低了类之间的耦合度,提高了系统的可维护性和可扩展性。

示例二:控制反转(IoC)和依赖注入(DI)

        控制反转和依赖注入允许我们将依赖关系外部化,并由容器或框架来管理。这样,类之间的依赖关系就变得更加灵活,降低了直接耦合。

// 接口
interface Service {void execute();
}// 具体服务类
class ConcreteService implements Service {@Overridepublic void execute() {System.out.println("Service executed");}
}// 客户端类
class Client {private Service service;// 构造器注入public Client(Service service) {this.service = service;}public void doSomething() {service.execute();}
}// 测试类
public class IoCDemo {public static void main(String[] args) {Service service = new ConcreteService();Client client = new Client(service);client.doSomething();}
}

        在这个示例中,Client 类通过构造器注入的方式依赖 Service 接口,而不是直接依赖 ConcreteService 类。这使得 Client 类更加灵活,可以轻松地替换 Service 的实现。

示例三:迪米特原则的反面示例与推荐用法

        下面通过一个业务场景来展示迪米特原则的反面示例和推荐用法。

反面示例

// 经理类
public class Manager {public void checkGoodsCount(Staff staff) {List<Good> goodList = new ArrayList<>();for (int i = 0; i < 20; i++) {goodList.add(new Good());}staff.checkCount(goodList);}
}// 员工类
public class Staff {public void checkCount(List<Good> goodList) {System.out.println("商品数量为: " + goodList.size());}
}// 商品类
public class Good {
}// 测试类
public class Main {public static void main(String[] args) {Manager manager = new Manager();Staff staff = new Staff();manager.checkGoodsCount(staff);}
}

        在这个反面示例中,Manager 类直接创建了 Good 对象的列表,并将其传递给 Staff 类。这违反了迪米特原则,因为 Manager 类不应该了解 Good 类的具体实现。

推荐用法

// 经理类
public class Manager {public void checkGoodsCount(Staff staff) {staff.checkCount();}
}// 员工类
public class Staff {public void checkCount() {List<Good> goodList = new ArrayList<>();for (int i = 0; i < 20; i++) {goodList.add(new Good());}System.out.println("商品数量为: " + goodList.size());}
}// 商品类
public class Good {
}// 测试类
public class Main {public static void main(String[] args) {Manager manager = new Manager();Staff staff = new Staff();manager.checkGoodsCount(staff);}
}

        在推荐用法中,Manager 类不再直接创建 Good 对象的列表,而是将创建列表的责任交给了 Staff 类。这样,Manager 类只需要知道 Staff 类的接口,而不需要了解 Good 类的具体实现,从而遵循了迪米特原则。

三、总结

        迪米特原则是面向对象设计中的一个重要原则,它强调一个对象应该对其他对象有最少的了解。通过降低类之间的耦合度,提高模块的相对独立性,迪米特原则有助于我们设计出更加灵活、可维护性更高的软件系统。在Java开发中,我们可以利用中介者模式、控制反转(IoC)和依赖注入(DI)、事件驱动编程以及模块化设计等技术来实现迪米特原则。然而,过分追求迪米特原则可能导致设计过于复杂,增加不必要的抽象层和中介者。因此,在使用迪米特原则时应适度应用,结合其他设计原则,关注实际场景,避免盲目追求理论上的完美设计。

相关文章:

迪米特原则的理解和实践

迪米特原则&#xff08;Law of Demeter&#xff0c;简称LoD&#xff09;&#xff0c;也被称为最少知识原则&#xff08;Least Knowledge Principle&#xff0c;LKP&#xff09;&#xff0c;是面向对象设计中的一个重要原则。其核心思想是&#xff1a;一个对象应该对其他对象有最…...

jQuery零基础入门速通(中)

大家好&#xff0c;我是小黄。 在上一篇文章中&#xff0c;我们初步了解了jQuery的基本概念、环境搭建、选择器、基本的DOM操作以及事件处理。接下来&#xff0c;我们将继续深入探讨jQuery的DOM操作和事件处理&#xff0c;以及一些实用的技巧和高级用法。 五、高级DOM操作 5…...

【设计模式系列】中介者模式(十八)

一、什么是中介者模式 中介者模式&#xff08;Mediator Pattern&#xff09;是一种行为型设计模式&#xff0c;其核心思想是通过一个中介者对象来封装一系列对象之间的交互&#xff0c;使这些对象不需要相互显式引用。中介者模式提供了一个中介层&#xff0c;用以协调各个对象…...

PDF版地形图矢量出现的问题

项目描述&#xff1a;已建风电场道路测绘项目&#xff0c;收集到的数据为PDF版本的地形图&#xff0c;图上标注了项目竣工时期的现状&#xff0c;之后项目对施工区域进行了复垦恢复地貌&#xff0c;现阶段需要准确的知道实际复垦修复之后的道路及其它临时用地的面积 解决方法&…...

小迪安全第四十二天笔记 简单的mysql注入 mysql的基础知识 用户管理数据库模式 mysql 写入与读取 跨库查询

前言 之前的安全开发我们学习了 php联动数据库的模式 &#xff0c;这个模式是现在常用的模式 这一节来学习 如何 进行数据库的注入和数据库相关知识 1、了解数据库的结构 我们使用 navicate连接数据库之后看一下 一共四层结构 库 》表》字段》数据 这个层级关系…...

11.25.2024刷华为OD

文章目录 HJ76 尼科彻斯定理&#xff08;观察题&#xff0c;不难&#xff09;HJ77 火车进站&#xff08;DFS&#xff09;HJ91 走格子方法&#xff0c;&#xff08;动态规划&#xff0c;递归&#xff0c;有代表性&#xff09;HJ93 数组分组&#xff08;递归&#xff09;语法知识…...

你真的会用饼图吗?JVS-智能BI饼图组件深度解析

在数据可视化的世界里&#xff0c;饼图是我们常见的一种可视化图形。在JVS-智能BI中提供了数据可视化饼图组件&#xff0c;接下来我通过这篇文章详细介绍&#xff0c;从配色方案到图形配置&#xff0c;从显示数据到提示信息&#xff0c;饼图的每一个细节配置。 饼图类图表概述…...

HarmonyOS Next 模拟器安装与探索

HarmonyOS 5 也发布了有一段时间了&#xff0c;不知道大家实际使用的时候有没有发现一些惊喜。当然随着HarmonyOS 5的更新也带来了很多新特性&#xff0c;尤其是 HarmonyOS Next 模拟器。今天&#xff0c;我们就来探索一下这个模拟器&#xff0c;看看它能给我们的开发过程带来什…...

医学机器学习:数据预处理、超参数调优与模型比较的实用分析

摘要 本文介绍了医学中的机器学习&#xff0c;重点阐述了数据预处理、超参数调优和模型比较的技术。在数据预处理方面&#xff0c;包括数据收集与整理、处理缺失值、特征工程等内容&#xff0c;以确保数据质量和可用性。超参数调优对模型性能至关重要&#xff0c;介绍了多种调…...

单片机知识总结(完整)

1、单片机概述 1.1. 单片机的定义与分类 定义&#xff1a; 单片机&#xff08;Microcontroller Unit&#xff0c;简称MCU&#xff09;是一种将微处理器、存储器&#xff08;包括程序存储器和数据存储器&#xff09;、输入/输出接口和其他必要的功能模块集成在单个芯片上的微型…...

【C++】auto和decltype类型推导关键字

1.C11关键字 auto和decltype是C11引入的关键字&#xff0c;负责类型的推导。所有不同的是&#xff1a; auto可直接用来定义变量&#xff0c;编译器会自动推导出变量的类型。decltype是推导出一个操作数的类型&#xff0c;然后用这个类型再去定义。 2.两者区别 尽管两者都是宏…...

OGRE 3D----3. OGRE绘制自定义模型

在使用OGRE进行开发时,绘制自定义模型是一个常见的需求。本文将介绍如何使用OGRE的ManualObject类来创建和绘制自定义模型。通过ManualObject,开发者可以直接定义顶点、法线、纹理坐标等,从而灵活地构建各种复杂的几何体。 Ogre::ManualObject 是 Ogre3D 引擎中的一个类,用…...

ARM + Linux 开发指南

随想:想写一个系列来讲如何嵌入式开发,然后能形成一个知识体系,帮助那些刚刚做嵌入开发的同学们. 1. ARM Linux从开机到Linux完全启动的流程和代码分析 ARM Linux从开机到完全启动的流程与代码分析 ARM Linux的启动过程主要涉及从设备上电开始,到Linux内核完全启动并进入…...

facebook欧洲户开户条件有哪些又有何优势?

在当今数字营销时代&#xff0c;Facebook广告已成为企业推广产品和服务的重要渠道。而为了更好地利用这一平台&#xff0c;广告主们需要理解不同类型的Facebook广告账户。Facebook广告账户根据其属性可分为多种类型&#xff0c;包括个人广告账户、企业管理&#xff08;BM&#…...

算法训练(leetcode)二刷第三十一天 | 1049. 最后一块石头的重量 II、494. 目标和、*474. 一和零

刷题记录 1049. 最后一块石头的重量 II*494. 目标和二维数组滚动数组 *474. 一和零 1049. 最后一块石头的重量 II leetcode题目地址 本题与416. 分割等和子集类似。依旧是01背包问题&#xff0c;本题尽可能将石头分为相等&#xff08;相近&#xff09;的两堆&#xff0c;然后…...

软件测试丨Pytest生命周期与数据驱动

Pytest的生命周期概述 Pytest 是一个强大的测试框架&#xff0c;提供了丰富的特性来简化测试执行。它的生命周期包括多个阶段&#xff0c;涉及从准备测试、执行测试到报告结果的完整流程。因此&#xff0c;理解Pytest的生命周期将帮助我们更好地设计和管理测试用例。 开始阶段…...

Figma入门-原型交互

Figma入门-原型交互 前言 在之前的工作中&#xff0c;大家的原型图都是使用 Axure 制作的&#xff0c;印象中 Figma 一直是个专业设计软件。 最近&#xff0c;很多产品朋友告诉我&#xff0c;很多原型图都开始用Figma制作了&#xff0c;并且很多组件都是内置的&#xff0c;对…...

网络安全防范技术

1 实践内容 1.1 安全防范 为了保障"信息安全金三角"的CIA属性、即机密性、完整性、可用性&#xff0c;信息安全领域提出了一系列安全模型。其中动态可适应网络安全模型基于闭环控制理论&#xff0c;典型的有PDR和P^2DR模型。 1.1.1 PDR模型 信息系统的防御机制能抵抗…...

Java - JSR223规范解读_在JVM上实现多语言支持

文章目录 1. 概述2. 核心目标3. 支持的脚本语言4. 主要接口5. 脚本引擎的使用执行JavaScript脚本执行groovy脚本1. Groovy简介2. Groovy脚本示例3. 如何在Java中集成 Groovy4. 集成注意事项 6. 与Java集成7. 常见应用场景8. 优缺点9. 总结 1. 概述 JSR223&#xff08;Java Spe…...

win10系统部署RAGFLOW+Ollama教程

本篇主要基于linux服务器部署ragflowollama&#xff0c;其他操作系统稍有差异但是大体一样。 一、先决条件 CPU ≥ 4核&#xff1b; RAM ≥ 16 GB&#xff1b; 磁盘 ≥ 50 GB&#xff1b; Docker ≥ 24.0.0 & Docker Compose ≥ v2.26.1。 如果尚未在本地计算机&#xff…...

AI 入门 30 天挑战 - Day 28 - 前沿技术概览

&#x1f31f; 完整项目和代码 本教程是 AI 入门 30 天挑战 系列的一部分&#xff01; &#x1f4bb; GitHub 仓库: https://github.com/Lee985-cmd/AI-30-Day-Challenge&#x1f4d6; CSDN 专栏: https://blog.csdn.net/m0_67081842?typeblog⭐ 欢迎 Star 支持&#xff01;…...

GetQzonehistory:3分钟永久备份你的QQ空间青春回忆,告别数据丢失焦虑

GetQzonehistory&#xff1a;3分钟永久备份你的QQ空间青春回忆&#xff0c;告别数据丢失焦虑 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 你是否曾经担心过QQ空间里那些珍贵的青春回…...

深入Acid引擎架构:模块化设计与现代C++17的最佳实践指南

深入Acid引擎架构&#xff1a;模块化设计与现代C17的最佳实践指南 【免费下载链接】Acid A high speed C17 Vulkan game engine 项目地址: https://gitcode.com/gh_mirrors/ac/Acid Acid引擎是一个基于Vulkan API的高性能C17游戏引擎&#xff0c;采用先进的模块化架构设…...

【2026实测】论文AI率居高不下?3大手改技巧与4款工具红黑榜

写文章现在最怕什么&#xff1f;查重&#xff1f;不&#xff0c;现在的风向变了——最怕的是AI率太高。 现在越来越多学校开始严查aigc报告&#xff0c;只要被判定AI率过重&#xff0c;直接打回重写甚至影响答辩资格。很多同学为了降低ai率&#xff0c;四处寻找各种免费降ai率…...

IMMACULATE框架:黑盒LLM服务的可验证审计技术

1. IMMACULATE框架解析&#xff1a;如何实现黑盒LLM服务的可验证审计在当今AI服务生态中&#xff0c;大型语言模型(LLM)正越来越多地以黑盒API的形式提供商业服务。用户支付费用获取文本生成能力&#xff0c;却无法验证服务商是否如约提供了承诺的模型质量和计算资源。这种信息…...

2025注安备考资料全套|视频+讲义+前导课,直接拿来就能学

大家好&#xff0c;最近很多备考注册安全工程师的同学都在找系统、完整的备考资料&#xff0c;要么是课程零散不全&#xff0c;要么是讲义和视频不配套&#xff0c;复习起来特别费劲。为了帮大家省去整理资料的时间&#xff0c;我把自己整理的2024-2025注安全套备考资料分享出来…...

2025届必备的降AI率助手实测分析

Ai论文网站排名&#xff08;开题报告、文献综述、降aigc率、降重综合对比&#xff09; TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 要降低那 AI 生成文本所呈现出的机械痕迹&#xff0c;就得从事先规划好的词汇、句法以及逻辑…...

用Python和NumPy手搓一个光流可视化工具:从理解数组到生成动态箭头图

用Python和NumPy手搓光流可视化工具&#xff1a;从数组操作到动态运动解析 光流分析是计算机视觉中理解物体运动的核心技术之一。想象一下&#xff0c;当你观看一段足球比赛视频时&#xff0c;如何用代码让计算机"看到"球员的跑动轨迹&#xff1f;这就是光流技术要解…...

一天2710亿Token!“爱马仕”反超“龙虾”,AI Agent进入真实用量竞争阶段

“爱马仕”登顶全球应用调用榜5月9日&#xff0c;Hermes Agent&#xff08;昵称&#xff1a;爱马仕&#xff09;登顶OpenRouter全球应用调用量榜首&#xff0c;首次超越OpenClaw&#xff08;昵称&#xff1a;龙虾&#xff09;。据OpenRouter应用Token消耗榜最新数据&#xff0c…...

终极指南:如何免费快速完成OFD转PDF的完整教程

终极指南&#xff1a;如何免费快速完成OFD转PDF的完整教程 【免费下载链接】Ofd2Pdf Convert OFD files to PDF files. 项目地址: https://gitcode.com/gh_mirrors/ofd/Ofd2Pdf 如果你经常处理电子发票、政府公文或电子证照&#xff0c;那么OFD转PDF的需求一定不陌生。O…...