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

news2024/11/24 13:07:59

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.coloradmin.cn/o/1260780.html

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

相关文章

14 网关实战:网关聚合API文档

上节课介绍了网关层的认证鉴权,今天这节介绍一下网关层如何聚合API接口文文档。 为什么需要聚合API接口文档? 大型微服务系统模块众多,木谷博客系统就有9个,如果这些服务的接口地址没有一个统一,那么客户端将要保存每个服务的接口地址,这个肯定是不现实。 先来看一下A…

小航助学题库蓝桥杯题库stem选拔赛(22年3月)(含题库教师学生账号)

需要在线模拟训练的题库账号请点击 小航助学编程在线模拟试卷系统&#xff08;含题库答题软件账号&#xff09;_程序猿下山的博客-CSDN博客 需要在线模拟训练的题库账号请点击 小航助学编程在线模拟试卷系统&#xff08;含题库答题软件账号&#xff09;_程序猿下山的博客-CSD…

Mo0n(月亮) MCGS触摸屏在野0day利用,强制卡死锁屏

项目:https://github.com/MartinxMax/Mo0n 后面还会不会在,我可就不知道了奥…还不收藏点赞关注 扫描存在漏洞的设备 #python3 Mo0n.py -scan 192.168.0.0/24 入侵锁屏 #python3 Mo0n.py -rhost 192.168.0.102 -lock 解锁 #python3 Mo0n.py -rhost 192.168.0.102 -unlock …

Jetpack Compose中适应性布局的新API

Jetpack Compose中适应性布局的新API 针对大屏幕优化的新组合件。 使用新的Material适应性布局&#xff0c;为手机、可折叠设备和平板电脑构建应用程序变得更加简单&#xff01;市场上各种不同尺寸的Android设备的存在挑战了构建应用程序时对屏幕尺寸的通常假设。开发者不应该…

什么是动态住宅IP?它有什么用途?

随着网络的迅速发展&#xff0c;许多人对代理IP已经有了比较深刻的认识&#xff0c;并且广泛地运用到了各自的业务中&#xff0c;尤其在跨境的相关业务中表现尤其卓越。对于代理IP的类别&#xff0c;也需要根据自己的业务类型具体选择最合适的&#xff0c;那么今天IPFoxy就给大…

TS 函数及多态

TS 能推导出函数体中的类型&#xff0c;但多数情况下无法推导出参数的类型&#xff0c;只有少数特殊情况下能根据上下文推导参数的类型。返回类型能推导出&#xff0c;不过也可以显式注解。 1 声明和调用函数 一般来说&#xff0c;在方法中的this值为调用该方法时位于点号左侧…

VsCode 调试 MySQL 源码

1. 启动 MySQL 2. 查看 MySQL 进程号 [root ~]# ps -ef | grep mysqld root 21479 1 0 Nov01 ? 00:00:00 /bin/sh /usr/local/mysql/bin/mysqld_safe --datadir/usr/local/mysql/data --pid-file/usr/local/mysql/data/mysqld.pid root 26622 21479 0 …

CSS新手入门笔记整理:CSS字体样式

字体类型&#xff1a;font-family 语法 font-family&#xff1a;字体1,字体2,...,字体n; font-family可以指定多种字体。使用多个字体时&#xff0c;将按从左到右的顺序排列&#xff0c;并且以英文逗号&#xff08;,&#xff09;隔开。如果我们不定义font-family&#xff0c…

Elasticsearch启动失败问题汇总

版本elasticsearch-8.11.1&#xff0c;解压安装完后&#xff0c;修改安装目录下conf/jvm.options&#xff0c; 默认配置如下&#xff1a; -Xms4g -Xmx4g 默认的配置占用内存太多了&#xff0c;调小一些&#xff1a; -Xms256m -Xmx256m由于es和jdk是一个强依赖的关系&#xff0…

代码随想录算法训练营第五十六天| 647. 回文子串 516.最长回文子序列

文档讲解&#xff1a;代码随想录 视频讲解&#xff1a;代码随想录B站账号 状态&#xff1a;看了视频题解和文章解析后做出来了 647. 回文子串 class Solution:def isPalindrome(self, string):left, right 0, len(string) - 1while left < right:if string[left] ! stri…

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…

智能AIGC写作系统ChatGPT系统源码+Midjourney绘画+支持GPT-4-Turbo模型+支持GPT-4图片对话

一、AI创作系统 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI…

Linux文件与路径

Linux文件与路径 1、文件结构 ​ Windows和Linux文件系统区别 ​ 在windows平台下&#xff0c;打开“此电脑”&#xff0c;我们可以看到盘符分区 ​ 每个驱动器都有自己的根目录结构&#xff0c;这样形成了多个树并列的情形 ​ 但是在 Linux 下&#xff0c;我们是看不到这些…

ECharts配置项手册了解及使用

1&#xff1a;点击文档然后选择配置项手册或者&#xff1a;Documentation - Apache ECharts 2&#xff1a;

某思路等考通一级MSOffice的分析

看到有朋友寻求2021版的等级考试一级软件&#xff0c;秉承授人以鱼不如授人以渔的理念&#xff0c;特写这个帖子。 某思路等考通一级MSOffice&#xff0c;版本6.5。 用到的软件&#xff0c;ScanId&#xff0c;de4dot,dnSpy。 第一步&#xff1a;分析 软件启动后有在线激活提示&…

1.6锁的升级过程

一、偏向锁 轻量级锁 当有新的线程进来时 其实就是竞争不激烈&#xff0c;但是确实存在多个锁竞争的情况&#xff0c;而且是&#xff0c;大家都很有序的进行&#xff0c;一释放&#xff0c;下一个线程就拿到锁&#xff0c;很有顺序的获取锁&#xff0c;基本上通过自旋的方式代…

leetcode:414. 第三大的数

一、题目 函数原型&#xff1a;int thirdMax(int* nums, int numsSize) 二、思路 将数组降序排序。 如果数组元素个数小于3&#xff0c;直接返回第一个元素&#xff1b; 如果数组元素个数大于等于3&#xff0c;且不同元素个数小于3&#xff0c;直接返回第一个元素&#xff1b; …

sqli-labs靶场详解less-24(二次注入)

less-24 对于一个像我一样的小白来说这关就像php代码审计 一开始进行判断注入点的时候怎么都找不到一点思路都没有 只能搜教程 说是二次注入 从来没遇见的题型 于是从代码审计开始 先说一下什么叫二次注入 二次注入 二次注入是指通过SQL语句存储到数据库的用户输入被读取后再次…

创建SpringBoot Helloword 程序详细步骤

本文档实现SpringBoot hello word 程序&#xff0c;翻译于Spring | Quickstart 目录 一、项目创建步骤1.1 创建项目1.2 添加代码1.3 运行 参考教程 一、项目创建步骤 1.1 创建项目 在官网Spring Initializr上创建项目 1.2 添加代码 在IDE中打开项目并在src/main/java/com/zo…

【数据结构】二叉树之链式结构

&#x1f525;博客主页&#xff1a; 小羊失眠啦. &#x1f3a5;系列专栏&#xff1a;《C语言》 《数据结构》 《Linux》《Cpolar》 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 文章目录 一、前置说明二、二叉树的遍历2.1 前序遍历2.2 中序遍历2.3 后序遍历2.4 层序遍历 三、…