迪米特法则(Law of Demeter, LoD)
——面向对象设计的“最少耦合”准则
一、定义与核心思想
-
核心定义
一个对象应尽可能少地与其他对象发生直接交互,仅与直接的朋友通信,避免依赖“陌生人”(即非直接耦合的类),从而降低系统耦合度。例如:- 校长通过教师类获取班级总分,而非直接访问学生类。
- 用户权限系统中,普通用户仅依赖读操作接口,管理员依赖读写接口。
-
核心思想
- 最少知识原则:对象对外部依赖的认知应最小化。
- 高内聚、松耦合:通过减少类间直接依赖,提升模块独立性与可维护性。
二、核心内容与约束
-
直接朋友的界定
- 合法交互对象:成员变量、方法参数、方法返回值中的类。
- 非法交互对象:局部变量中的类或通过其他对象间接获取的类(如
a.getB().getC()
)([13] [14])。
-
实现约束
- 不暴露内部细节:类仅通过定义明确的接口与外界交互。
- 避免链式调用:禁止跨层调用(如
objA.getB().getC().method()
)。
三、优势与价值
优势 | 应用价值 |
---|---|
1. 降低耦合:模块间依赖减少,修改影响范围可控。 2. 提升可维护性:代码逻辑清晰,调试与扩展成本低。 3. 增强复用性:松耦合的模块更易被复用。 | 1. 减少风险:避免局部修改引发全局崩溃。 2. 简化测试:依赖减少,单元测试更易实现。 |
四、实现方式
-
封装与接口设计
- 隐藏非必要方法:通过接口仅暴露最小功能集。
- 示例:
改进:教师类封装班级总分计算逻辑,校长仅调用// 反例:跨层调用违反 LoD class School { void getClassScore(Teacher teacher) { List<Student> students = teacher.getClass().getStudents(); // 直接调用学生类方法,违反 LoD } }
teacher.getClassTotalScore()
。
-
设计模式应用
- 门面模式(Facade):通过统一接口封装子系统(如支付系统聚合多种支付方式)。
- 中介者模式(Mediator):通过中介类管理对象间通信(如聊天室消息转发)。
五、应用场景
- 分层架构
- 数据访问层通过接口提供查询服务,业务层不直接操作数据库细节。
- 微服务通信
- 服务间通过 API 网关交互,避免直接依赖彼此的具体实现。
- 插件化系统
- IDE 主程序仅依赖插件接口,不感知插件内部逻辑。
六、与其他原则的协同
- 单一职责原则(SRP)
- SRP 确保类职责单一,LoD 进一步限制职责外露。
- 合成复用原则(CARP)
- 当继承导致过度依赖时,优先使用组合。
- 依赖倒置原则(DIP)
- DIP 通过抽象解耦,LoD 限制依赖范围。
七、注意事项
- 避免过度设计
- 简单场景(如工具类)无需强制拆分中介。
- 平衡性能与解耦
- 多层封装可能增加调用链,高频场景需优化。
- 中介类管理
- 防止中介类泛滥,合理规划职责边界。
总结
迪米特法则通过最小化对象间的直接依赖,构建了松耦合、高内聚的软件架构。其本质是面向对象设计的“边界控制”实践,核心价值在于提升系统的稳定性和可维护性。实际开发中需结合场景,灵活运用封装与设计模式,在解耦与性能间找到平衡。