迪米特原则(设计默斯和)

news/发布时间2024/8/24 23:08:48

定义

 高内聚低耦合是一个非常重要的设计思想,能够很好的提高代码的可读性和可维护性,缩小功能改动导致导致代码改动范围,实际上,在前面的章节中,我们已经多次提到了这个设计思想。很多设计原则都是以代码的高内聚低耦合为目的的,比如单一原则,基于接口而非编程实现

实际上,高内部松耦合,是一个比较通用的设计思路,可以用来指导不同粒度的设计于开发,比如系统,模块,类,甚至函数。也亦可以应用到不同的开发场景中,比如微服务,框架组件,类库等。为了方便讲解,我们以类作为这个设计思想的应用对象来展开讲解。其他的应用场景你可以自行类比。 

高内聚

它说的是讲相近的功能放到同一个类中,不相近的功能放在不同的类中,相近的功能往往被同时修改,代码的维护比较容易,实际上,我们前边讲解的单一原则,是高内聚非常有效的原则,

松耦合

所谓松耦合,在代码中,类鱼类之间的依赖关系简单清晰。即使两个类有依赖关系,一个类的改动不会后者很多好导致依赖类的代码的改动。实际上我们之前的依赖注入,基于接口而非实现,以及今天讲的迪米特原则都是为了实现代码的松耦合。 

内聚合耦合之间的关系

高内聚有助于实现松耦合,同理低耦合也会导致紧耦合。 关于这一点,下边的一张对比如来解释。

左边部分的代码的设计中,类的粒度比较小,每个类的职责比较单一,行进的功能都放在一个类中,不相近的功能放在了多个类中。这样类更加独立,代码的内聚性更高。 右边的代码的设计中,类的粒度比较大,低内聚,功能大而全,不相近的功能放到了一个类中。这就导致了很多其他类都依赖这个类。当我们修改这个类的某一个功能代码的时候,会影响依赖它的多个类。 我们需要测试这三个依赖类。是否正常工作。这就是所谓的牵一发而动全身。 

除此之外,从图中我们可以看出,高内聚低耦合的代码更加的简单,清晰,响应的在可维护和可读性上确实高了很多。 

迪米特原则: 

每个模块直应该了解那些于它关系密切的模块的有限知识。或者说,每个模块只能和自己的朋友说话,不要和陌生人说话。 

具体实战

public class NetworkTransporter {// 省略属性和其他方法...public Byte[] send(HtmlRequest htmlRequest) {
//...}
}
public class HtmlDownloader {private NetworkTransporter transporter;// 通过构造函数或 IOC 注入public Html downloadHtml(String url) {Byte[] rawHtml = transporter.send(new HtmlRequest(url));return new Html(rawHtml);}
}
public class Document {private Html html;private String url;public Document(String url) {this.url = url;HtmlDownloader downloader = new HtmlDownloader();this.html = downloader.downloadHtml(url);}
}

  

我们来看NetworkTransporter类,作为一个底层网络通信类,我们希望它尽可能的通用,而不知服务于下载html ,所以我们不应该直接依赖太具体的发送对象HtmlRequest。从这一点上讲,NetworkTransporter类的设计违背了迪米特原则,依赖不该直接依赖的关系的HtmlRequest类。 

我们应该如何重构,让NetworkTransporter 类满足迪米特法则呢? 我这里有一个形象的比喻,加入你线程需要去商店买东西,你看到你定不会直接把浅包给收银员。让收银员从你的钱包力拿钱。而是你从钱包力把钱拿出来交给收银员。 这里的HtmlRequest 就相当于钱包,HtmlRequest 里边的address 和context 对象就相当于钱。我们应该把address 和context 交割NetworkTransporter ,而不死把HtmlRequest 交给NetworkTransporter 。根据这个思路。NetworkTransporter 重构之后的代码如下: 

public class NetworkTransporter {// 省略属性和其他方法...public Byte[] send(String address, Byte[] data) {//...}
}

  

最后我们来看Document 类。这个类。主要有三点,1.构造函数的downloader.downloadHtml() 逻辑复杂,耗时长,不应该放到构造函数中,会影响代码的可测试性。HtmlDownloader对象在构造函数中通过new 来创建的,违反了基于接口而非编程的设计思想。 也会影响代码的可测试性。从业务上,Document 网页文档没必要依赖HtmDownloader 类,违背了迪米特原则

public class Document {private Html html;private String url;public Document(String url, Html html) {this.html = html;this.url = url;}
//...
}
// 通过一个工厂方法来创建 Document
public class DocumentFactory {private HtmlDownloader downloader;public DocumentFactory(HtmlDownloader downloader) {this.downloader = downloader;}public Document createDocument(String url) {Html html = downloader.downloadHtml(url);return new Document(url, html);}
}

  

现在,我们再来看以下这条原则的后半部分,有依赖关系的类之间,尽量只依赖必要的接口。 

 

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

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

相关文章

7-2. 场景互动的逻辑实现

创建可互动接口实现宝箱代码using System.Collections; using System.Collections.Generic; using UnityEngine;public class Chest : MonoBehaviour, IInteractable {private SpriteRenderer spriteRenderer;public Sprite openSprite;public Sprite closeSprite;public bool …

PCDN边缘计算盒子X86机顶盒路由器,边缘计算源头厂家代理加盟

自主研发核心算法,跑量好,收益高! 专注于大数据处理、云计算服务的科技创新型平台服务商,作为源头厂家,可根据客户需求提供边缘计算一站式解决方案:软硬件开发、CDN各大云厂商业务直签,业务成熟稳定,资源变现快。成本低,方案多,效率高。 PCDN代理加盟,电话/微信:13…

doubletrouble 双重麻烦

doubletrouble 双重麻烦 一 信息收集 IP扫描端口扫描80目录扫描访问 uploads访问 secret 发现图片下载 图片安装工具 谷歌网址 https://github.com/RickdeJager/stegseek/releases解压字典解析图片查看 output 得到 邮箱 和 密码登录 80 网页二 漏洞利用 1 上传反弹s…

GDOI2024 考前模拟2 T2

题目描述题解 考虑黑用 \(1\) 表示,白用 \(0\) 表示,那么Alice要赢,就意味着每条边 \(x\rightarrow y\) 等价于 \(clr[x]\le clr[y]\)。连边也就是 \(\le\) 的关系。 不妨编号从 \(0\) 开始,题目的染色方式则意味着 \(clr[x]\neq clr[x\bigoplus 1]\)。那么原图里有 \(x\ri…

MySQL:Data too long for column 成果简介 at row 1

MySQL导入数据时只导入了结构而没有导入数据 检查发现报错:Data too long for column 成果简介 at row 1 解决方法—— 将过长的文件类型更改为text即可

声明式管理

声明式管理 离线式的修改 kubectl expose pod nginx-d9d8cf5c7-rcdsg --name hanbao-shutiao --type=NodePort --port=9090 --target-port=80 #将端口改为8800,nodeport改为4371 #4371不在端口范围内,所以报错 #改为43710 在线修改#修改为立即生效#将名字修改 #报错 所以…

读人工不智能:计算机如何误解世界笔记05_人的问题

人的问题1. 人的问题 1.1. 关于教育和数字技术的观点似乎来自很多不同的作者和思想家 1.2. 计算机系统是它们制作者的代言人 1.3. 由于历史上创建计算机系统的人并没有什么多样性可言,技术系统的设计和概念中有一些嵌入的信念,我们最好重新思考…

CMU 15-445(Fall 2023) Project4 Concurrency Control个人笔记

CMU 15-445(Fall 2023) Project4 Concurrency Control个人笔记Task #1 - Timestamps 1.1 Timestamp Allocation 每个事务开始时,会为其分配一个读取时间戳,其值为最新的事务提交时间戳,当一个版本的时间戳小于等于事务的读取时间戳时,代表该版本对于当前事务是可读的。 提交…

BEST Drive智能驾驶解决方案

BEST Drive智能驾驶解决方案 Drive Brain基于大算力量产芯片 Drive Brain-面向L3级别智能驾驶域控的多传感器解决方案 多传感器解决方案 基于黑芝麻智能华山系列A1000高性能芯片,配合摄像头,毫米波雷达,激光雷达等 感知融合加以高精度地图,实现可以前装量产的高等级智能驾驶…

html网页版音乐播放器

利用html+css+js 实现网页版音乐播放,支持歌词预览,歌曲上一曲下一曲暂停顺序播放循环播放等功能 先上效果图:歌曲部分: 音乐路径为拼接指定路径下的音乐文件url,无需用户手动选取文件路径 歌词部分: 通过ajax获取歌词lyric文本,js解析每句歌词的播放时间和内容 html代码:<d…

代码随想录算法训练营day07 | leetcode 454. 四数相加 II、383. 赎金信、15. 三数之和、18. 四数之和

目录题目链接:454. 四数相加 II-中等题目链接:383. 赎金信-简单题目链接:15. 三数之和-中等题目链接:18. 四数之和-中等 题目链接:454. 四数相加 II-中等 题目描述: 给你四个整数数组 nums1、nums2、nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l…

ssts-hospital-web-master项目实战记录二十六:项目迁移-Hook实现(useDataStore)

记录时间:2024-02-27 一、useDataStore模块实现 store/useDataStore.tsimport { defineStore } from pinia import {DICT_PAGE,DICT_COMMON,DICT_DEVICE,DICT_SYSTEM,DICT_STATIC,DICT_NULL,DICT_CONFIG,DICT_OUT } from @/constexport const useDataStore = defineStore(data…

【力扣】反转链表II

题目描述思路 老样子,还是先用递归试试。 在基本问题中,也就是left == rigth或者left+1 == right时,直接将两个元素调换顺序即可。 我突然发现代码随想录里好像讲过一个用双指针法反转链表的算法。 那道题是把整个链表翻转, 代码如下: //双指针法 class Solution { public…

Java学习第一天MarkDown学习

MarkDown语法学习 文本编辑器:typoraTypora 官方中文站) 文件后缀xxx.md 样式 标题: (几级标题用几个#号)+空格+标题内容+空格+# 字体样式: fk JAVA fk JAVA fk JAVA fk JAVA 引用: 大于号+空格+引言我一定能学完Java分割线:三个---或者三个*图片超链接 名字 列表代码

【Filament】绘制圆形

1 前言 ​ Filament环境搭建中介绍了 Filament 的 Windows 和 Android 环境搭,绘制三角形中介绍了绘制纯色和彩色三角形,绘制矩形中介绍了绘制纯色和彩色矩形,本文将使用 Filament 绘制圆形。 2 绘制圆形 ​ 本文项目结构如下,完整代码资源 → Filament绘制圆形。2.1…

P7745 [COCI2011-2012#3] ROBOT

考试的题目。nnd,欺负我不会二分!Description 在一个平面直角坐标系中,有一个点 bot,现有四个指令,分别可以让 bot 向上、下、左、右四个方向中的一个移动一格。同时还有 \(n\) 个固定点,求每次移动后这些点到 bot 的哈曼顿距离之和。两个点 \((x1, y1)\) 和 \((x2, y2\)…

安装虚拟机(Windows)

虚拟机安装过程: 1.首先创建一台新的虚拟机2.什么都不用做直接下一步3.点击稍后安装操作系统4.选择第一个Windows,版本选择Windows 10 x64![]5.输入虚拟机的名称和安装位置6.选择你需要的磁盘大小,下面都可以选7.点击完成8.然后开始设置虚拟机9.调整内存10.选择处理器的数量…

4.3 隐马尔可夫模型(HMM)

原理: 起始概率、发射概率和跳转概率三套参数可以完整地描述任意一个HMM模型起始概率:第一回合隐状态所有取值的概率发射概率:每一种隐状态可能对应的所有可观测状态的概率(发生某种隐状态的前提下再发生每种可观测状态的概率)转移状态:各个隐状态之间转换的概率应用: 模…

创新指南|2023 年及以后新兴 SaaS 趋势

SaaS 行业正在迅速蓬勃发展,并且在未来几年不会放缓。其正在经历由新兴趋势推动的重大变革,这些趋势正在重塑基于云的应用程序的格局。在本文中,我们将探讨 2024 年及以后的一些新兴 SaaS 趋势。SaaS 行业正在迅速蓬勃发展,并且在未来几年不会放缓。其正在经历由新兴趋势推…

【教程】iOS上获取崩溃日志的N+1种方法

引言 在移动应用开发过程中,经常会遇到应用程序崩溃的情况。为了更好地排查和解决这些崩溃问题,获取崩溃日志是至关重要的。本文将介绍多种在iOS设备上获取崩溃日志的方法,帮助开发者快速定位问题并进行修复。 摘要 本文介绍了在iOS设备上获取崩溃日志的多种方法,包括从系统…
推荐文章