迪米特法则(LoD)
当然可以!这次我们来讲解迪米特法则(Law of Demeter, LoD),又叫最少知识原则(Least Knowledge Principle)。
我将从 定义 → 为什么需要 → 优缺点 → Python 示例 → 逻辑结构图 全面拆解,助你真正理解。
🧠 什么是迪米特法则(LoD)?
迪米特法则:一个对象应尽可能少地了解其他对象的内部细节。
换句话说:
“你只能和你直接的朋友说话,而不要和朋友的朋友说话。”
🎯 更通俗解释:
- ❌ 不要这样:
a.b.c.d.doSomething()
- ✅ 应该这样:
a.doSomething()
你不需要了解 b
是谁、c
是什么结构、d
有没有方法。
✅ 为什么需要 LoD?
好处 | 说明 |
---|---|
降低耦合度 | 每个类只关心与它直接关联的对象 |
提高封装性 | 对象对外暴露尽可能少的细节 |
代码更可维护 | 当内部结构变了,不影响外部依赖 |
更易于重构 | 接口更稳定、组件更独立 |
❌ 迪米特法则的缺点?
缺点 | 说明 |
---|---|
封装层数多 | 为了避免链式访问,可能需要增加中转方法 |
代码“跳转多” | 每一层都写封装方法,会让代码看起来“冗长” |
初期复杂度提升 | 需要花精力设计 API 接口的合理暴露边界 |
🐍 Python 示例
❌ 违反迪米特法则
class Engine:def start(self):print("Engine started")class Car:def __init__(self):self.engine = Engine()class Driver:def drive(self, car: Car):car.engine.start() # ❌ 直接访问 Car 的子对象 Engine
这里 Driver
不应该关心 Car
的 engine
,这是“朋友的朋友”。
✅ 遵守迪米特法则
class Engine:def start(self):print("Engine started")class Car:def __init__(self):self.engine = Engine()def start_engine(self): # ✅ 对外暴露接口self.engine.start()class Driver:def drive(self, car: Car):car.start_engine() # ✅ 只调用 Car 的公开方法
Driver
只与Car
交互,而不需要知道engine
的存在。Car
对engine
进行封装,符合“最少知识”。
🧭 逻辑图(Mermaid)
🧩 应用场景(适用 vs 不适用)
✅ 推荐使用 LoD 的场景:
- 多层嵌套结构(如 MVC、网络传输、领域模型)
- 微服务调用时保护 API 边界
- 大型系统中模块解耦设计
❌ 不推荐使用的场景:
- 简单脚本、性能敏感代码(层层封装可能会带来性能瓶颈)
- 极简数据访问(例如直接调用
data.id
)
🏁 总结一句话
迪米特法则=“最少知道” + “别越界”
只操作你直接信任的对象,不要过度了解或依赖别人的内部实现,否则系统就变得脆弱。
如果你希望,我可以再画一张**“违反 vs 遵守”的对比图**,或者做个“真实场景案例”比如 Web Controller 层应用 LoD 的封装模式。
想继续深入哪部分?图示对比、还是实战代码?✨