java设计模式之迪米特法则使用场景分析
一、避免链式调用
场景描述:当代码中存在多层对象嵌套调用(如A.getB().getC().doSomething()
)时,调用者需了解多个对象的内部结构,导致耦合度升高。
解决方案:通过封装中间逻辑,将调用链拆分为独立方法,仅暴露必要接口。
案例:
- 反例:
customer.getOrder().getOrderItem().getProduct().getName()
,Customer
类直接依赖Order
、OrderItem
、Product
的实现。 - 正例:在
Customer
类中添加getProductName()
方法,内部封装链式调用逻辑,外部仅需调用customer.getProductName()
。
二、封装内部实现细节
场景描述:类的内部数据结构(如集合、复杂对象)若直接暴露给外部,可能被随意修改,破坏封装性。
解决方案:通过只读方法或不可变集合返回内部数据,限制外部直接操作。
案例:
- 反例:
ShoppingCart
类直接返回List
,外部可修改购物车商品列表。 - 正例:返回
Collections.unmodifiableList(products)
,并通过addProduct()
和removeProduct()
方法控制操作。
三、中介者模式协调复杂交互
场景描述:多个对象间存在复杂依赖关系,直接交互导致代码冗余和耦合。
解决方案:引入中介者类统一管理交互逻辑,减少对象间的直接依赖。
案例:
- 反例:
AllInOneDevice
类直接调用Printer
和Scanner
的具体方法。 - 正例:定义
Device
接口,由DeviceManager
类协调所有设备操作,具体设备仅实现接口方法。
四、模块化设计与职责分离
场景描述:类承担了过多职责,或直接依赖非核心对象,导致职责混乱。
解决方案:明确类的职责边界,通过委托或接口隔离实现解耦。
案例:
- 反例:
Driver
类直接操作Car
和Engine
,违反职责单一原则。 - 正例:
Car
类封装Engine
的细节,仅提供startCar()
接口,Driver
仅与Car
交互。
五、减少中间层依赖
场景描述:高层模块直接依赖底层实现细节,导致系统扩展困难。
解决方案:通过抽象接口或中间层隔离具体实现。
案例:
- 反例:
SchoolManager
类直接操作CollegeManager
的CollegeEmployee
列表。 - 正例:
CollegeManager
提供getEmployeeCount()
方法,SchoolManager
仅调用该方法获取统计信息。
六、信息隐藏与接口最小化
场景描述:类暴露了过多内部方法或属性,增加被误用风险。
解决方案:限制成员访问权限(如使用private
/protected
),仅暴露必要方法。
案例:
- 反例:
Engine
类公有字段直接被Car
类外访问。 - 正例:
Engine
仅提供getFuelType()
方法,Car
类封装具体实现细节。
七、适用场景总结
- 大型复杂系统:模块间交互频繁时,通过迪米特法则降低耦合,提升可维护性。
- 频繁变更的模块:封装细节后,内部修改不影响外部调用。
- 第三方库集成:隐藏底层实现,仅暴露稳定接口。
八、注意事项
避免过度封装:可能引入冗余中介类,增加系统复杂度。
- 权衡性能:间接调用可能带来额外性能开销,需结合场景评估。
通过合理应用迪米特法则,可构建高内聚、低耦合的系统架构,显著提升代码的可扩展性和可维护性。实际开发中需结合其他原则(如单一职责、开闭原则)综合设计。