当前位置: 首页 > java >正文

java设计模式之迪米特法则使用场景分析

一、避免链式调用

场景描述:当代码中存在多层对象嵌套调用(如A.getB().getC().doSomething())时,调用者需了解多个对象的内部结构,导致耦合度升高。
解决方案:通过封装中间逻辑,将调用链拆分为独立方法,仅暴露必要接口。
案例:

  • 反例:customer.getOrder().getOrderItem().getProduct().getName()Customer类直接依赖OrderOrderItemProduct的实现。
  • 正例:在Customer类中添加getProductName()方法,内部封装链式调用逻辑,外部仅需调用customer.getProductName()

二、封装内部实现细节

场景描述:类的内部数据结构(如集合、复杂对象)若直接暴露给外部,可能被随意修改,破坏封装性。
解决方案:通过只读方法或不可变集合返回内部数据,限制外部直接操作。
案例:

  • 反例:ShoppingCart类直接返回List,外部可修改购物车商品列表。
  • 正例:返回Collections.unmodifiableList(products),并通过addProduct()removeProduct()方法控制操作。

三、中介者模式协调复杂交互

场景描述:多个对象间存在复杂依赖关系,直接交互导致代码冗余和耦合。
解决方案:引入中介者类统一管理交互逻辑,减少对象间的直接依赖。
案例:

  • 反例:AllInOneDevice类直接调用PrinterScanner的具体方法。
  • 正例:定义Device接口,由DeviceManager类协调所有设备操作,具体设备仅实现接口方法。

四、模块化设计与职责分离

场景描述:类承担了过多职责,或直接依赖非核心对象,导致职责混乱。
解决方案:明确类的职责边界,通过委托或接口隔离实现解耦。
案例:

  • 反例:Driver类直接操作CarEngine,违反职责单一原则。
  • 正例:Car类封装Engine的细节,仅提供startCar()接口,Driver仅与Car交互。

五、减少中间层依赖

场景描述:高层模块直接依赖底层实现细节,导致系统扩展困难。
解决方案:通过抽象接口或中间层隔离具体实现。
案例:

  • 反例:SchoolManager类直接操作CollegeManagerCollegeEmployee列表。
  • 正例:CollegeManager提供getEmployeeCount()方法,SchoolManager仅调用该方法获取统计信息。

六、信息隐藏与接口最小化

场景描述:类暴露了过多内部方法或属性,增加被误用风险。
解决方案:限制成员访问权限(如使用private/protected),仅暴露必要方法。
案例:

  • 反例:Engine类公有字段直接被Car类外访问。
  • 正例:Engine仅提供getFuelType()方法,Car类封装具体实现细节。

七、适用场景总结

  1. 大型复杂系统:模块间交互频繁时,通过迪米特法则降低耦合,提升可维护性。
  2. 频繁变更的模块:封装细节后,内部修改不影响外部调用。
  3. 第三方库集成:隐藏底层实现,仅暴露稳定接口。

八、注意事项

避免过度封装:可能引入冗余中介类,增加系统复杂度。

  • 权衡性能:间接调用可能带来额外性能开销,需结合场景评估。
    通过合理应用迪米特法则,可构建高内聚、低耦合的系统架构,显著提升代码的可扩展性和可维护性。实际开发中需结合其他原则(如单一职责、开闭原则)综合设计。
http://www.xdnf.cn/news/18042.html

相关文章:

  • 佳文赏读 || (CVPR 2025新突破) Robobrain:机器人操作从抽象到具体的统一大脑模型(A Unified Brain Model)
  • 魔搭api功能优化
  • 栈与队列:数据结构中的双生子
  • 【P14 3-6 】OpenCV Python——视频加载、摄像头调用、视频基本信息获取(宽、高、帧率、总帧数),视频保存在指定位置
  • 在职老D渗透日记day18:sqli-labs靶场通关(第26关)get报错注入 过滤or和and基础上又过滤了空格和注释符 ‘闭合 手动注入
  • qt vs2019编译QXlsx
  • Linux软件编程(六)(exec 函数族、system 实现、进程回收与线程通信)
  • C++ 内存管理(内存分布 , 管理方式 , new和delete实现原理)
  • pidgen!DecodeProdKey函数分析之iDecodedBytesMax
  • 服务器硬件电路设计之I2C问答(七):解析 I2C 通信 “卡壳” 难题:从设备无响应与跨电压兼容之道
  • Spring AI Starter和文档解读
  • InfluxDB 数据迁移工具:跨数据库同步方案(一)
  • 超酷炫的Three.js示例
  • Java:File类、递归、字符集、IO流体系及Commons-io框架
  • 【大模型核心技术】Dify 入门教程
  • Flow-GRPO:通过在线 RL 训练 Flow matching 模型
  • PS插件整合包!内置数百款PS插件,支持PS2017-PS2025所有版本!
  • 【学习嵌入式day-26-线程间通信】
  • TypeScript快速入门
  • CPP多线程3:async和future、promise
  • ArrayList的contains问题
  • 机器学习 [白板推导](十二)[卡曼滤波、粒子滤波]
  • 第G7周:Semi-Supervised GAN 理论与实战
  • 【科研绘图系列】R语言绘制雷达图
  • 洛谷B3865 [GESP202309 二级] 小杨的 X 字矩阵(举一反三)
  • 从 MySQL 5.7 迁移到 8.0:别让 SQL 文件 “坑” 了你
  • 《从入门到高可用:2025最新MySQL 8.0全栈速通指南》
  • Linux配置Dante使用的pam验证
  • 【攻防实战】红队攻防之Goby反杀
  • 力扣(LeetCode) ——622. 设计循环队列(C语言)