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

组件互相依赖到改一个崩三个?中介者模式来拆弹

我刚接手一个航班搜索模块的时候,被代码的耦合度吓到了。

航班选择器改了出发城市,要通知价格计算器重新报价;价格变了,要通知行李额度组件刷新;行李额度变了,又反过来影响价格。六个组件互相持有对方的引用,改一个组件的接口,另外五个全部编译报错。

画成依赖关系图就是一个蜘蛛网,没有任何人敢动这个模块。

这种"网状依赖"的问题,中介者模式一句话就能解决:所有组件不直接互相通信,而是通过一个中间人(中介者)来协调。

最直观的例子:机场调度塔

飞机之间不需要互相通信——A 飞机不需要知道 B 飞机的位置。所有飞机只跟调度塔说话。

```java // 中介者接口 public interface ATC { void requestTakeoff(Aircraft aircraft); void requestLanding(Aircraft aircraft); void notifyRunwayCleared(Aircraft aircraft); }

// 具体中介者 public class ControlTower implements ATC { private Queue landingQueue = new LinkedList<>(); private boolean runwayBusy = false;

@Override public void requestTakeoff(Aircraft aircraft) { if (!runwayBusy) { runwayBusy = true; aircraft.takeoff(); } else { System.out.println(aircraft + " 等待跑道"); } } @Override public void requestLanding(Aircraft aircraft) { if (!runwayBusy) { runwayBusy = true; aircraft.land(); } else { landingQueue.offer(aircraft); } } @Override public void notifyRunwayCleared(Aircraft aircraft) { runwayBusy = false; if (!landingQueue.isEmpty()) { Aircraft next = landingQueue.poll(); runwayBusy = true; next.land(); } }

}

// 同事类(组件) public class Aircraft { private ATC atc; private String name;

public Aircraft(String name, ATC atc) { this.name = name; this.atc = atc; } public void requestTakeoff() { atc.requestTakeoff(this); } public void requestLanding() { atc.requestLanding(this); } public void takeoff() { System.out.println(name + " 起飞"); } public void land() { System.out.println(name + " 降落"); }

} ```

你看,Aircraft 类完全不知道其他飞机的存在,它只认识 ATC(调度塔)。增删飞机不影响任何其他飞机的代码。

回到航班搜索的实际场景

把那个蜘蛛网一样的模块改造成中介者模式后,结构变成了星形:

```java public class SearchMediator { private FlightSelector flightSelector; private PriceCalculator priceCalculator; private BaggageChecker baggageChecker; private InsurancePanel insurancePanel;

public void onFlightChanged(String flightNo) { priceCalculator.recalculate(flightNo); baggageChecker.reset(flightNo); insurancePanel.update(flightNo); } public void onBaggageChanged(Baggage baggage) { priceCalculator.adjustForBaggage(baggage); } public void onPriceChanged(BigDecimal newPrice) { insurancePanel.updatePremium(newPrice); }

} ```

每个组件只持有 Mediator 的引用,不直接持有其他组件。改了 BaggageChecker 的接口,只有 Mediator 需要改,其他组件完全不受影响。

你可能已经用过了

MVC 架构里的 Controller 就是一个中介者。Model 和 View 互不通信,都通过 Controller 协调。

Java 的 java.util.Timer 内部也是中介者模式的思路——TimerTask 不需要知道其他 Task 的存在,Timer 统一管理调度。

连前端的 Redux/Vuex 本质上也是中介者——组件不直接互相通信,而是通过全局 Store(中介者)来共享状态。

别滥用的忠告

中介者模式最大的陷阱是中介者本身变成一个上帝类。所有逻辑都塞进 Mediator,它膨胀到几千行,变成整个系统的瓶颈。这种情况其实比你原来的网状依赖还糟,至少原来问题分散在各个组件里,现在全集中到一个类了。

我们的做法是按业务域拆分中介者。价格相关的事件放 PriceMediator,航班状态相关放 FlightMediator,不要什么都往一个 Mediator 里塞。Mediator 应该是一个薄协调层,不应该包含具体的业务计算逻辑。

另一个常见问题:事件风暴。组件 A 触发事件 -> Mediator 通知组件 B -> B 改变了状态 -> 又触发事件 -> Mediator 通知 A -> A 又改变状态... 循环调用。解决办法是在 Mediator 里维护一个事件处理标记,同一轮事件中不再重复派发。

微信搜「爪爪代码冒险记」,漫画闯关学设计模式,23种模式全在里面。

http://www.jsqmd.com/news/947402/

相关文章:

  • STM32 Bootloader跳转App跑飞?一个PSP指针引发的HardFault血案(附CubeMX工程对比)
  • Activiti 7数据库表结构全解析:从act_re到act_ru,看完这篇就懂了
  • 工业吸尘器品牌选择要点:从性能到服务的全面解析 - 品牌排行榜
  • XUnity.AutoTranslator终极指南:开启游戏无障碍翻译新时代
  • 在 Rust 中从头开始训练 LLM
  • Step 3.5 Flash:面向工业API的7B大模型推理范式重构
  • 2026 江苏南通全域商铺 / 办公室工装优选榜单|门面整装、商场改造、写字楼翻新 3 家正规装修企业实测测评 + 本地化避坑全攻略 - 本地便民网
  • DLSS Swapper终极指南:3分钟学会游戏性能优化神器
  • 别再被0.1+0.2≠0.3搞懵了!从IEEE 754标准出发,手把手带你理解浮点数的‘规格化’与‘非规格化’
  • AI巡检,让CMDB更干净
  • 工业智能一体机和商用一体机差价在哪?拆开看内部
  • 评价超高!这家固定式集装箱翻转机直销厂家究竟有何过人之处?
  • 莫瑶教育全品类AI课程全景解读:三大黄金赛道,覆盖从技术研发到商业变现的全链路成长路径 - 全国职业学校推荐官
  • 告别示教器:用C#写个WinForm小工具,实时监控ABB机器人状态和日志
  • 金融大模型社招|RAG 搜索 / 大模型算法 / 大模型安全
  • 8款最佳AI视频生成器及使用方法(2026)
  • 别再对着型号发愁了!手把手教你解读国产DJ接插件命名规则(附AMP对照表)
  • DeepSeek-V4深度解析:长记忆与强Agent协同架构
  • 3分钟颠覆传统:百度网盘提取码智能获取工具如何重构你的数字资源世界
  • 保姆级教程:用FrontEnd Plus和十六进制编辑器破解Java试用版限制(附字节码修改原理)
  • 零基础福音:在快马平台跟着ai生成的互动指南完成python首次安装
  • LLVM IR指令避坑指南:`nuw`/`nsw`、`exact`这些关键字用错了会怎样?
  • 质量好的工业吸尘器选购要点与品牌解析 - 品牌排行榜
  • 【Redis从入门到精通】第44篇:Sentinel启动与监控——它是怎么盯着主服务器的
  • 实战指南:基于快马生成生产级PyTorch模型推理镜像与部署方案
  • PHP风控系统与反欺诈策略
  • 学生编程入门最佳AI编程工具最新推荐:8款实测工具搞定作业、课程项目与竞赛
  • 让 Agent 具备业务常识的三种策略
  • 别再死记硬背!用‘客户服务系统’实战案例,轻松搞懂UML类图与包图设计
  • 从零到一:在CentOS服务器上为Tesla K80双卡配置CUDA深度学习环境(实测记录)