类别: 原则
类型: 面向对象设计原则
来源: 美国东北大学 Demeter 项目,约 1987 年由 Ian Holland 等提出
别名: 最少知识原则
类型: 面向对象设计原则
来源: 美国东北大学 Demeter 项目,约 1987 年由 Ian Holland 等提出
别名: 最少知识原则
快速回答 — 迪米特法则(Law of Demeter)主张:一个模块应只和“关系近”的对象交互,不要穿透多层对象内部结构。它的核心价值是降低耦合,让系统在结构变化时更稳。
什么是迪米特法则?
迪米特法则(Law of Demeter)是一条边界规则:对象的方法应只调用自身、直接字段、方法参数以及本方法新建对象的方法。让“直接协作者替你完成动作”,而不是“自己一路钻进别人的内部结构”。在代码里,这通常表现为避免
a.getB().getC().doX() 这类“火车式调用链”。它和单一职责原则、关注点分离、快速失败原则一起使用时,能显著降低改动扩散。
迪米特法则的三层理解
- 入门:少写长链调用,让直接对象暴露你真正需要的动作。
- 实践:用意图清晰的门面方法隐藏深层导航逻辑。
- 进阶:把它当作“变更半径控制器”,用于架构边界设计。
起源
该法则来自美国东北大学的 Demeter 项目,相关思想在 1980 年代后期由 Ian Holland 的研究与后续论文体系化。 它最初要解决的是可维护性问题:当调用方深度依赖被调对象的内部结构时,内部字段或对象关系一变,外层大量代码会连锁破坏。 后来这一原则被广泛吸收进工程实践,成为控制对象耦合、提升可演化性的常用设计准则。核心要点
迪米特法则不是语法洁癖,而是协作边界管理方法。应用场景
你可以在编码、评审和 API 设计阶段持续应用这条原则。后端服务分层
通过服务层意图方法替代深层仓储-领域对象链式调用,减少跨层依赖。
前端状态管理
用 selector 或视图模型适配器替代深层 props 读取,降低组件耦合。
SDK 与公共库 API
暴露稳定入口,避免用户依赖库内部对象图细节。
团队代码评审
将“火车式调用链”列为高优先级重构信号,定期治理。
经典案例
在订单系统重构中,一个常见做法是将深层对象链读取改为聚合边界上的门面方法。公开工程复盘中,多团队都报告这种改造能降低“改一个模型牵动多模块”的连锁影响。 可量化指标通常是“单需求涉及文件数”和“发布后回归缺陷数”。当调用深度被压缩、边界方法稳定后,这两项指标通常会下降,说明变更面被有效收敛。边界与失效场景
迪米特法则有效,但过度执行会产生副作用。- 包装层膨胀:过多中转方法会让代码变啰嗦、语义变弱。
- 接口贫血:过度隐藏结构会影响高级场景的组合能力。
- 形式合规:语法上“看似符合”,语义上仍可能强耦合。
常见误区
团队常把它误解为“禁止任何点号链式写法”。误区:迪米特法则等于不能链式调用
误区:迪米特法则等于不能链式调用
纠正:稳定语义的 Fluent API 与泄漏内部结构的深层导航不是同一件事。
误区:包装方法越多越好
误区:包装方法越多越好
纠正:只有能表达意图并隔离变更的封装才有价值。
误区:它只适用于 OOP 教条场景
误区:它只适用于 OOP 教条场景
纠正:核心思想是“局部交互、控制扩散”,在任何架构都成立。
相关概念
迪米特法则与以下概念组合时效果更稳定。单一职责原则
模块职责越单一,协作边界越清晰,越容易遵守最少知识通信。
关注点分离
先做好层次隔离,才能从根源减少跨层穿透调用。
最小权限原则
在安全领域采用同样思想:只授予最小必要访问范围。