设计模式—迪米特原则(LOD)

1.背景

1987年秋天由美国Northeastern University的Ian Holland提出,被UML的创始者之一Booch等普及。后来,因为在经典著作《 The Pragmatic Programmer》而广为人知。

2.概念

迪米特法则(Law of Demeter)又叫作最少知识原则(The Least Knowledge Principle),一个类对于其他类知道的越少越好,就是说一个对象应当对其他对象有尽可能少的了解,只和朋友通信,不和陌生人说话。英文简写为: LOD。

通俗的讲:

  • 不该知道的不要知道;

  • 一个类应该保持对其它对象最少的了解,只和朋友通信,不和陌生人说话;

  • 降低类之间的耦合度;

  • 从依赖者的角度来说,只依赖应该依赖的对象;

  • 从被依赖者的角度说,只暴露应该暴露的方法;

设计原则:

  • 在类的划分上,应该创建弱耦合的类。类与类之间的耦合越弱,就越有利于实现可复用的目标;

  • 在类的结构设计上,尽量降低类成员的访问权限;

  • 在类的设计上,优先考虑将一个类设置成不变类;

  • 在对其他类的引用上,将引用其他对象的次数降到最低;

  • 不暴露类的属性成员,而应该提供相应的访问器(set 和 get 方法);

  • 谨慎使用序列化(Serializable)功能;

3.案例

需求:租客想通过中介找房子,租客想要一个20平、2000一个月的。

方案一(不满足迪米特原则):把所有房源都给租客,租客自己选

/// <summary>/// 房源/// </summary>public class Room{private int are;private int pay;public int getAre(){return are;}public void setAre(int are){this.are = are;}public int getPay(){return pay;}public void setPay(int pay){this.pay = pay;}}/// <summary>/// 中介/// </summary>public class Mediator{private List<Room> allRooms = new List<Room>();/// <summary>/// 初始化房源/// </summary>public Mediator(){for (int i = 0; i < 10; i++){Room room = new Room();room.setAre((i + 1) * 5);room.setPay((i % 4 == 0 ? 1 : i % 4) * 1000);allRooms.Add(room);}}/// <summary>/// 获取所有房源/// </summary>/// <returns></returns>public List<Room> GetAllRooms(){return allRooms;}}/// <summary>/// 租客/// </summary>public class Tenant{public static void RentRoom(Mediator mediator){// 通过中介获取所有房屋List<Room> allRoom = mediator.GetAllRooms();foreach(Room room in allRoom){if (IsSuitable(room)){Console.WriteLine("房屋找到了");}}}/// <summary>/// 判断房子是否满足客户需求/// </summary>/// <param name="room"></param>/// <returns></returns>private static bool IsSuitable(Room room){// 筛选房屋return true;}}{//LOD:迪米特原则Tenant.RentRoom(new Mediator());}

代码分析:

以上的方案是中介直接把所有的房源全部提供给顾客,其中就包含不满足租客条件的房源,这就增加了租客和房源直接的耦合度。

方案二(满足迪米特原则):先按照要求把房源筛选出来,给租客

/// <summary>/// 房源/// </summary>public class Room{private int are;private int pay;public int getAre(){return are;}public void setAre(int are){this.are = are;}public int getPay(){return pay;}public void setPay(int pay){this.pay = pay;}}/// <summary>/// 中介/// </summary>public class MediatorLOD{private List<Room> allRooms = new List<Room>();public MediatorLOD(){for (int i = 0; i < 10; i++){Room room = new Room();room.setAre((i + 1) * 5);room.setPay((i % 4 == 0 ? 1 : i % 4) * 1000);allRooms.Add(room);}}/// <summary>/// 找出符合租客要求的房子/// </summary>/// <param name="are"></param>/// <param name="pay"></param>/// <returns></returns>public Room RentRoom(int are, int pay){// 通过中介获取所有房屋foreach(Room room in allRooms){if (IsSuitable(room, are, pay)){return room;}}return null;}/// <summary>/// 判断房源是否满足客户的要求/// </summary>/// <param name="room"></param>/// <param name="are"></param>/// <param name="pay"></param>/// <returns></returns>private bool IsSuitable(Room room, int are, int pay){// 筛选房屋return true;}}/// <summary>/// 租客/// </summary>public class TenantLOD{/// <summary>/// 获取满足条件的房源/// </summary>/// <param name="mediator"></param>public static void RentRoom(MediatorLOD mediator){Console.WriteLine(mediator.RentRoom(20, 2000));}}{//LOD:迪米特原则Tenant.RentRoom(new Mediator());}

代码分析:

相比方案一,当前方案把筛选的过程放到了租客能联系到的中介身上,中介处理房源,而租客和房源的联系微乎其微,这就利用了LOD 原则,降低了租客和房源的耦合度,租客只看到符合条件的房源就可以了。

4.优缺点

优点:

  • 降低了类之间的耦合度,使类与类之间保持松散的耦合关系;

  • 由于耦合度降低,提高了模块的相对独立性;

  • 提高类的可复用性和系统的扩展性;

缺点:

  • 迪米特法则是一种面向对象系统设计风格的一种法则,尤其适合做大型复杂系统设计指导原则。但是也会造成系统的不同模块之间的通信效率降低,使系统的不同模块之间不容易协调等。

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

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

相关文章

c语言,输入整数n(行数,本例为4),按照如下规则打印数字图片 1 5 9 13 2 6 10 14 3 7 11 15 4 8 12 16

c语言&#xff0c;输入整数n(行数&#xff0c;本例为4&#xff09;&#xff0c;按照如下规则打印数字图片 1 5 9 13 2 6 10 14 3 7 11 15 4 8 12 16 以下是使用C语言编写的程序&#xff0c;根据输入的行数打印数字图片的规则&#xff1a; #include <stdio.h>int main() …

【LeeCode】59.螺旋矩阵II

给定一个正整数 n&#xff0c;生成一个包含 1 到 n^2 所有元素&#xff0c;且元素按顺时针顺序螺旋排列的正方形矩阵。 示例: 输入: 3 输出: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ] 解&#xff1a; class Solution {public int[][] generateMatrix(int n) {int[][] ar…

Mysql编写过程和解析过程顺序刨析

我们在平时的编写sql语句当中&#xff0c;编写顺序都是知道&#xff0c;先select …… from …… join……where 等等 &#xff0c;那么它的解析过程顺序是什么样的呢&#xff1f;先说一下mysql解析顺序大致为&#xff1a; FROM 子句的解析&#xff1a; 解析 FROM 子句时&…

CV计算机视觉每日开源代码Paper with code速览-2023.11.22

点击CV计算机视觉&#xff0c;关注更多CV干货 论文已打包&#xff0c;点击进入—>下载界面 点击加入—>CV计算机视觉交流群 1.【语义分割】Mobile-Seed: Joint Semantic Segmentation and Boundary Detection for Mobile Robots 论文地址&#xff1a;https://arxiv.or…

7种SQL进阶用法【转】

1.自定义排序(ORDER BY FIELD) 在MySQL中ORDER BY排序除了可以用ASC和DESC之外,还可以使使用自定义排序方式来实现 CREATE TABLE movies ( id INT PRIMARY KEY AUTO_INCREMENT, movie_name VARCHAR(255), actors VARCHAR(255), price DECIMAL(10,2) DEFAULT 50, release date…

P8安全基本理论A001-CIA安全模型-使用PGP描述网络安全CIA模型之私密性、完整性案例

【教学资源名称】 CIA安全模型-使用PGP描述网络安全CIA模型之私密性、完整性案例 【预备知识】 在信息安全等级保护工作中,根据信息系统的机密性(Confidentiality)、完整性(Integrity)、可用性(Availability)来划分信息系统的安全等级,三个性质简称CIA。 私密性(Confi…

ES 8.x开始(docker-compose安装、kibana使用、java操作)

学习文档地址 一、Docker安装 这里使用docker-compose来安装&#xff0c;方便后续迁移&#xff0c;Elasticserach和kibina一起安装。 1、创建安装目录 configdataplugins 2、配置文件 配置文件有两个&#xff0c;一个是ES的配置文件&#xff0c;一个docker-compose的配置文件 …

大厂做项目的过程,你真的知道吗?

文章目录 明确需求排期代码设计技术选型写代码迭代更新 一线大厂的项目是如何从0-1被做出来的&#xff0c;了解大厂项目开发的详细流程&#xff1b;自己开发项目那是单打独斗&#xff0c;没人管你&#xff1b;但进入企业中开发项目那是开团打本&#xff0c;大家都在一股绳上&am…

龙芯loongarch64服务器编译安装pyarrow

1、简介 pyarrow是一个高效的Python库,用于在Python应用程序和Apache Arrow之间进行交互。Arrow是一种跨语言的内存格式,可以快速高效地转移大型数据集合。它提供了一种通用的数据格式,将数据在内存中表示为表格,并支持诸如序列化和分布式读取等功能。 龙芯的Python仓库安…

Ubuntu 22.03 LTS 安装deepin-terminal 分屏

安装 源里面自带了这个软件&#xff0c;可以直接装 sudo apt install deepin-terminal 启动 按下Win键&#xff0c;输入deep即可快速检索出图标&#xff0c;点击启动 效果 分屏 CtrlShiftH 水平分割 CtrlShiftJ 垂直分割 最多分割成四个小窗口&#xff0c;鼠标点击可以切换…

[ BUG ] 踩坑 Axios Delete 请求传参

踩坑 Axios Delete 请求传参 问题描述 今天在写前后端交互时&#xff0c;我想将 data 数据通过 delete 进行传参 axios.delete("/info", data)&#xff0c;但是发现后端一直提示参数错误&#xff0c;我看了看代码也没错啊。跟 post、patch 一样的写法为什么会出现参…

三方支付接口成为了电商竞争力的新动力

在当前快速发展的互联网时代&#xff0c;随着电子商务行业的兴起&#xff0c;支付体验已经成为企业获取竞争优势的重要因素。一个快速、安全、便捷的支付环节不仅可以提升用户的体验&#xff0c;还能有效促进交易的完成。在众多支付解决方案中&#xff0c;三方支付接口因其独特…

18.Spring框架中的单例bean是线程安全的吗?(阿里一面)

Spring框架中的单例bean是线程安全的吗?(阿里一面) 不是,Spring框架中的单例bean不是线程安全的。spring 中的 bean 默认是单例模式,spring 框架并没有对单例 bean 进行多线程的封装处理。 实际上大部分时候 spring bean 无状态的(比如 dao 类),所以某种程度上来说 bea…

PCL 计算点云图中任意两点的欧式距离

目录 一、算法原理二、代码实现三、结果展示四、相关链接本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT。 一、算法原理 使用PCL实现在可视化界面上用鼠标点选两个点,输出两点的坐标和两点之间的欧式距离。 二、代码…

linux 内核线程

内核线程类似于用户进程&#xff0c;通常用于并发处理些工作&#xff0c;它是一种在内核空间实现后台任务的方式&#xff0c;并且可以参与时间片轮转调度。 内核线程可以进行繁忙的异步事件处理&#xff0c;也可以睡眠等待某事件的发生&#xff0c;内核线程可以访问内核函数和…

Linux操作系统使用及C高级编程-D17D18编译与调试

编译 当有线程创建时编译&#xff1a;gcc test.c -o test -lpthread 分文件编写时主要是分为&#xff1a;.c&#xff08;函数声明的具体实现&#xff09;、.h&#xff08;说明性文件&#xff1a;#define 结构体共用体 声明&#xff09;、.c(main) 条件编译 一般情况下&#x…

激光线提取

在做单线激光三维重建&#xff0c;和多线激光三维重建的时候都会设计到激光线提取算法的实现&#xff0c;如何保持高速和高精度是关键 &#xff0c;最近优化了steger中心线提取算法&#xff0c;通过并行化实现在cpu版本可以做到2m,GPU版本可以做到0.6ms左右&#xff0c;完全可…

Flask 运用Xterm实现交互终端

Xterm是一个基于X Window System的终端仿真器&#xff08;Terminal Emulator&#xff09;。Xterm最初由MIT开发&#xff0c;它允许用户在X Window环境下运行文本终端程序。Xterm提供了一个图形界面终端&#xff0c;使用户能够在图形桌面环境中运行命令行程序。而xterm.js是一个…

Kotlin学习——kt入门合集博客 kt里的委派模式Delegation kt里的特性

Kotlin 是一门现代但已成熟的编程语言&#xff0c;旨在让开发人员更幸福快乐。 它简洁、安全、可与 Java 及其他语言互操作&#xff0c;并提供了多种方式在多个平台间复用代码&#xff0c;以实现高效编程。 https://play.kotlinlang.org/byExample/01_introduction/02_Functio…

23. Spring源码篇之环境变量Environment

简介 在开发过程中&#xff0c;我们通常会把一些变化的数据&#xff0c;或者说不同环境值不一样的数据抽离出来&#xff0c;代码可以根据需要通过配置动态的方式获取不同的值&#xff0c;这个值可以是在配置文件中&#xff0c;数据库中等 在spring中定义了一个统一的环境变量…