【设计模式笔记07】:迪米特法则

文章目录

      • 迪米特法则 (LoD)
        • [1. 定义](#1. 定义)
        • [2. "朋友"的界定](#2. “朋友”的界定)
        • [3. 典型应用](#3. 典型应用)
        • [4. 实例:CRM系统界面控件交互](#4. 实例:CRM系统界面控件交互)

迪米特法则 (LoD)

1. 定义

迪米特法则,也称为最少知识原则 (LKP),它有多种定义方式,但核心思想都是一致的。

  • 定义1 (最通俗的) : 不要和"陌生人"说话。 (Don't talk to strangers.)

    • 这个定义非常形象地表达了原则的精髓。一个对象应该尽可能少地了解其他对象的内部细节。
  • 定义2 (进一步解释) : 只与你的直接朋友通信。

    • 这引出了一个关键概念:"朋友"。接下来会详细解释什么是"朋友"。
  • 定义3 (最正式的) : 每一个软件单位对其他的单位都都只有最少的知识,而且局限于那些与本单位密切相关的软件单位。

    • 这里的"软件单位"可以指一个类、一个模块或一个函数。这个定义强调了知识的"局部化",避免信息在系统中不必要地传播。
2. "朋友"的界定

理解迪米特法则的关键在于理解什么是"直接朋友"。

  • 耦合与朋友关系:

    • 在面向对象的世界里,每个对象都会与其他对象有耦合关系 。只要两个对象之间有耦合关系,就说这两个对象之间是朋友关系
    • 耦合的方式很多,如依赖、关联(组合与聚合)等。
  • 直接朋友 (Direct Friends):

    • 对于一个类(比如类 A)来说,它的"直接朋友"包括以下几种:
      1. A 自身的成员变量所引用的对象。
      2. A 中某个方法的方法参数所引用的对象。
      3. A 中某个方法的方法返回值所引用的对象。
      4. A 自身的对象(this)。
  • "陌生人" (Strangers):

    • 迪米特法则要求,陌生的类最好不要以局部变量的形式出现在类的内部。
    • 一个类只与它的直接朋友通信,而以局部变量形式出现的类不是该类的直接朋友。
    • 典型的违反场景 : 连续的 . 调用,如 a.getB().getC().doSomething()。在这个链式调用中,a 是朋友,但 bc 对象对于当前类来说就是"陌生人"。我们通过朋友 a 的"介绍"认识了陌生人 b,又通过 b 认识了 c,这违反了"只和直接朋友说话"的原则。
3. 典型应用
  • 外观模式 (Facade Pattern)中介者模式 (Mediator Pattern) 都是迪米特法则的典型应用。
    • 外观模式: 为一个复杂的子系统提供一个统一的、简化的接口。客户端只需要与这个外观接口(直接朋友)交互,而不需要了解子系统内部众多类(陌生人)的复杂关系。
    • 中介者模式: 用一个中介对象来封装一系列的对象交互。各个对象不再直接相互引用,而是都只与中介者(直接朋友)通信,由中介者协调它们之间的交互,将网状的复杂关系变为星状的简单关系。
4. 实例:CRM系统界面控件交互
  • a. 初始设计 (违反LoD)
    • 场景: 一个CRM系统包含很多业务操作窗口,在这些窗口中,某些界面控件之间存在复杂的交互关系。一个控件事件的触发将导致多个其他界面控件产生响应。
    • 具体例子 : 当一个按钮 Button 被单击时,对应的列表框 List、组合框 ComboBox、文本框 TextBox 和文本标签 Label 等都将发生改变。
    • 设计方案: 在初始设计中,这些界面控件之间直接进行交互,形成了一个复杂的网状结构。
  • 问题分析:

    • 高耦合 : Button 类直接了解并调用了 ListComboBox 等多个控件的细节,反之亦然。每个控件都认识了太多"朋友",导致它们之间紧密耦合。
    • 扩展性差 : 如果此时需要增加一个新的界面控件(例如一个 CheckBox),并且它需要与现有控件交互,那么可能需要修改多个与之交互的其他控件的源代码,系统扩展性较差,需要重构。
  • b. 重构后的设计 (遵循LoD)

    • 重构目标: 降低界面控件之间的耦合度,使它们不再直接交互。
    • 解决方案 : 引入一个中介类 (Mediator),专门用于控制界面控件之间的交互。

图片描述 :重构后的UML对象图。Button, List, Label, ComboBox, TextBox 不再相互关联,而是都只与中心的Mediator类发生关联,形成了一个星型结构。

  • 工作流程 :
    1. 所有的控件(如 Button)都只认识中介者 Mediator 这个"直接朋友"。
    2. Button 被点击时,它不会直接去操作 ListTextBox,而是通知中介者 Mediator:"我被点击了"。
    3. 中介者 Mediator 接收到请求后,再由它来完成对其他控件(List, TextBox 等)的调用和协调。
  • 重构后优点 :
    • 低耦合: 界面控件之间不再产生直接引用,它们都只依赖于中介者。
    • 高内聚: 每个控件只负责自己的行为和通知中介者,而复杂的交互逻辑被封装在中介者内部。
    • 易于维护和扩展: 如果要修改交互逻辑,只需要修改中介者类。如果要增加新的控件,也只需要让它和中介者交互即可,对现有控件类的影响降到了最低。这完美地体现了迪米特法则的精神。
相关推荐
三品吉他手会点灯6 小时前
C语言学习笔记 - 43.运算符与表达式 - 运算符1 - 运算符的分类和简单介绍
c语言·笔记·学习·算法
疯狂打码的少年6 小时前
中断处理过程与中断优先级
笔记
心之伊始6 小时前
Java 后端接入大模型:从 Token、并发到推理成本的完整估算方法
java·spring boot·性能优化·大模型·llm
likerhood7 小时前
WSL 下安装 Miniconda 笔记
笔记·wsl
BlackTurn7 小时前
技术经理投标
java
YG亲测源码屋7 小时前
java配置环境变量、jdk环境变量配置、java环境变量设置方法
java·开发语言
MIUMIUKK7 小时前
从语法层面,看懂 Python 的特殊处
java·开发语言·python
hujinyuan201607 小时前
2026年3月 中国电子学会青少年软件编程(Python)三级考试试卷 真题及答案
java·python·算法
basketball6168 小时前
C++ 高级编程:2. 基本线程池实现
java·开发语言·c++
MageGojo8 小时前
天气 API 接入实战:基于 ApiZero 实现实时天气、分钟级降水和 15 天预报查询
java·后端·spring·api 接口接入·接口实战