资讯动态

Java 23 种设计模式:从踩坑到精通 | 番外:中介者模式 —— 物流服务协调实战

发布时间:2026/8/12 9:42:11 来源:尧图企业网站定制
Java 23 种设计模式从踩坑到精通 | 番外中介者模式 —— 物流服务协调实战摘要中介者模式用一个中介对象来封装一系列对象的交互使各对象不需要显式地相互引用从而使其耦合松散将网状的多对多依赖关系转变为以中介者为中心的星型结构。本文结合智能物流调度中心的场景完整展示如何用中介者协调订单、库存、配送三大服务的交互并与外观模式深度对比帮你掌握“化网为星”的设计精髓。️本文阅读地图3 分钟速览为什么订单、库存、配送服务不能直接互相调用中介者核心角色抽象中介者、具体中介者、抽象同事、具体同事手写物流调度中心订单创建 → 库存扣减 → 配送发货全程由中介者协调中介者 vs 外观双向协调 vs 单向简化面试必问“中介者模式和外观模式有什么区别DispatcherServlet用了哪个”《Java 23 种设计模式从踩坑到精通》开篇系列介绍与目录 正篇Mediator 中介者模式 —— 对象关系太乱请一位“中间人” 当前番外 · 中介者模式 × 物流服务协调 返回系列总目录1. 物流服务交互的痛点在智能物流系统中订单服务、库存服务、配送服务之间存在紧密的协作关系订单创建后需要通知库存扣减库存确认后需要通知配送发货配送完成后需要通知订单更新状态。如果让这三个服务直接互相调用// 订单服务直接依赖库存服务和配送服务classOrderService{privateInventoryServiceinventoryService;privateDeliveryServicedeliveryService;voidcreateOrder(){inventoryService.deductStock();// 直接调用库存deliveryService.arrangeDelivery();// 直接调用配送}}这种写法会让服务之间形成网状依赖——每新增一个服务如支付服务、通知服务所有相关服务都要修改。更糟糕的是服务之间的调用顺序和交互规则散落在各服务内部难以统一管理和动态调整。中介者模式的解决思路引入一个调度中心中介者让所有服务只与调度中心通信不再直接互相调用。订单创建后通知调度中心调度中心决定接下来调用库存服务库存确认后再由调度中心调用配送服务——所有交互逻辑集中在调度中心内各服务只需关注自己的业务。1.1 你的场景该不该用中介者判断标准是 → 用中介者否 → 用其他方式多个对象之间形成复杂的网状交互耦合严重✅❌交互逻辑频繁变化需要集中管理和动态调整✅❌希望各组件独立开发、独立测试✅❌只有简单的一对一调用关系无网状依赖❌直接调用即可2. 中介者模式 UML物流调度中心场景3. 完整源码实现3.1 抽象中介者接口 (Mediator)/** * 抽象中介者定义同事类通知中介者的统一接口 */publicinterfaceMediator{voidnotify(Colleaguesender,Stringevent);}白话中介者只有一个核心方法——接收来自某个同事的消息然后决定下一步通知谁。3.2 抽象同事类 (Colleague)/** * 抽象同事类所有具体同事的基类 */publicabstractclassColleague{protectedMediatormediator;protectedStringname;publicColleague(Mediatormediator,Stringname){this.mediatormediator;this.namename;}publicabstractvoidsend(Stringevent);publicabstractvoidreceive(Stringevent);}白话每个同事都持有中介者的引用发消息走中介者收消息也从中介者来。同事之间互不相识。3.3 具体中介者物流调度中心 (ConcreteMediator)/** * 具体中介者物流调度中心协调各服务之间的交互 */publicclassConcreteMediatorimplementsMediator{privateConcreteColleagueAorderService;privateConcreteColleagueBinventoryService;privateConcreteColleagueCdeliveryService;Overridepublicvoidnotify(Colleaguesender,Stringevent){System.out.println(\n [调度中心] 收到来自 [sender.name] 的消息event);if(senderorderService){handleOrderEvent(event);}elseif(senderinventoryService){handleInventoryEvent(event);}elseif(senderdeliveryService){handleDeliveryEvent(event);}}privatevoidhandleOrderEvent(Stringevent){if(event.contains(已创建)){System.out.println( → 调度中心通知库存服务扣减库存);inventoryService.receive(订单已创建请扣减库存);}}privatevoidhandleInventoryEvent(Stringevent){if(event.contains(库存充足)){System.out.println( → 调度中心通知配送服务安排发货);deliveryService.receive(库存已确认请安排配送);}elseif(event.contains(库存不足)){System.out.println( → 调度中心通知订单服务取消订单);orderService.receive(库存不足订单已取消);}}privatevoidhandleDeliveryEvent(Stringevent){if(event.contains(已发货)){System.out.println( → 调度中心通知订单服务更新物流状态);orderService.receive(商品已发货物流单号SF123456789);}}publicvoidsetOrderService(ConcreteColleagueAorderService){this.orderServiceorderService;}publicvoidsetInventoryService(ConcreteColleagueBinventoryService){this.inventoryServiceinventoryService;}publicvoidsetDeliveryService(ConcreteColleagueCdeliveryService){this.deliveryServicedeliveryService;}}白话调度中心是“大脑”——它知道所有服务所有交互规则都写在这里。订单创建后该做什么、库存确认后该做什么全部集中管控。新增一个服务只需在中介者中增加对应的处理方法。3.4 具体同事类订单/库存/配送服务/** * 具体同事类A订单服务 */publicclassConcreteColleagueAextendsColleague{publicConcreteColleagueA(Mediatormediator,Stringname){super(mediator,name);}Overridepublicvoidsend(Stringevent){System.out.println( [name] 发送消息event);mediator.notify(this,event);}Overridepublicvoidreceive(Stringevent){System.out.println( [name] 收到消息event);}}/** * 具体同事类B库存服务 */publicclassConcreteColleagueBextendsColleague{publicConcreteColleagueB(Mediatormediator,Stringname){super(mediator,name);}Overridepublicvoidsend(Stringevent){System.out.println( [name] 发送消息event);mediator.notify(this,event);}Overridepublicvoidreceive(Stringevent){System.out.println( [name] 收到消息event);if(event.contains(扣减库存)){booleanhasStocktrue;// 模拟库存充足if(hasStock){send(库存充足扣减完成);}else{send(库存不足无法扣减);}}}}/** * 具体同事类C配送服务 */publicclassConcreteColleagueCextendsColleague{publicConcreteColleagueC(Mediatormediator,Stringname){super(mediator,name);}Overridepublicvoidsend(Stringevent){System.out.println( [name] 发送消息event);mediator.notify(this,event);}Overridepublicvoidreceive(Stringevent){System.out.println( [name] 收到消息event);if(event.contains(安排配送)){send(已发货物流单号SF123456789);}}}白话每个服务只做两件事——send发消息给中介者receive收消息并执行自己的业务逻辑。它们完全不知道其他服务的存在。3.5 客户端测试publicclassClient{publicstaticvoidmain(String[]args){ConcreteMediatordispatchernewConcreteMediator();ConcreteColleagueAorderServicenewConcreteColleagueA(dispatcher,订单服务);ConcreteColleagueBinventoryServicenewConcreteColleagueB(dispatcher,库存服务);ConcreteColleagueCdeliveryServicenewConcreteColleagueC(dispatcher,配送服务);dispatcher.setOrderService(orderService);dispatcher.setInventoryService(inventoryService);dispatcher.setDeliveryService(deliveryService);System.out.println( 场景用户下单触发完整物流流程 \n);orderService.send(订单已创建订单号20240723001);System.out.println(\n 流程结束 );}}4. 运行结果 场景用户下单触发完整物流流程 [订单服务] 发送消息订单已创建订单号20240723001 [调度中心] 收到来自 [订单服务] 的消息订单已创建订单号20240723001 → 调度中心通知库存服务扣减库存 [库存服务] 收到消息订单已创建请扣减库存 [库存服务] 发送消息库存充足扣减完成 [调度中心] 收到来自 [库存服务] 的消息库存充足扣减完成 → 调度中心通知配送服务安排发货 [配送服务] 收到消息库存已确认请安排配送 [配送服务] 发送消息已发货物流单号SF123456789 [调度中心] 收到来自 [配送服务] 的消息已发货物流单号SF123456789 → 调度中心通知订单服务更新物流状态 [订单服务] 收到消息商品已发货物流单号SF123456789 流程结束 5. 核心角色回顾角色职责对应代码Mediator定义同事与中介者的通信接口MediatorConcreteMediator协调各同事的交互集中管控规则ConcreteMediatorColleague持有中介者引用通过中介者通信ColleagueConcreteColleague实现自身业务发消息给中介者ConcreteColleagueA/B/C6. 中介者模式 vs 外观模式对比项中介者模式外观模式意图协调多个对象之间的双向交互为子系统提供单向统一入口通信方向同事 ↔ 中介者 ↔ 同事双向客户端 → 外观 → 子系统单向子系统感知同事类知道中介者的存在子系统不知道外观的存在典型应用物流调度中心、聊天室、DispatcherServletSLF4J、JdbcTemplate、微服务网关一句话记忆中介者是“中控台”——双向协调每个服务都知道中介者外观是“一键启动”——单向简化子系统不知道外观的存在。7. 中介者模式的优缺点优点缺点同事类之间零依赖从网状变星型中介者可能膨胀为“上帝类”交互逻辑集中管控修改方便所有通信经过中介者可能成为性能瓶颈各组件可独立开发、独立测试设计复杂度增加8. 六大设计原则体现原则体现单一职责同事负责自身业务中介者负责协调开闭原则新增同事类通常无需修改中介者新增交互规则时需修改里氏替换所有同事可替换抽象Colleague依赖倒置同事依赖抽象Mediator接口接口隔离Mediator只有notify()一个方法迪米特法则同事只与中介者通信不知其他同事存在附 中介者模式 UML源码物流调度中心场景startuml title Java 23 种设计模式从踩坑到精通 footer 折哥 | 智能物流与Java实战 1. 全局样式配置 skinparam backgroundColor #FEFEFE skinparam shadowing false skinparam classBorderColor #333333 skinparam classFontColor #1A1A1A skinparam classFontSize 14 skinparam noteFontSize 12 skinparam noteFontColor #555555 skinparam arrowColor #555555 skinparam classBackgroundColor #F9F9F9 skinparam interface { BackgroundColor #E8F5E9 BorderColor #2E7D32 } 2. 抽象中介者 interface Mediator { notify(sender, event) } note right of Mediator b抽象中介者/b -- 定义同事类通知中介者的统一接口 封装对象间的交互逻辑 end note 3. 具体中介者 class ConcreteMediator implements Mediator { - colleagueA : ConcreteColleagueA - colleagueB : ConcreteColleagueB notify(sender, event) setColleagueA(Colleague) setColleagueB(Colleague) } note right of ConcreteMediator b具体中介者/b -- 协调各同事类之间的交互 知道所有同事类但同事类不知道彼此 end note 4. 抽象同事类 abstract class Colleague { - mediator : Mediator send(event) receive(event) } note right of Colleague b抽象同事类/b -- 持有中介者引用 通过中介者与其他同事通信 不直接依赖其他同事类 end note 5. 具体同事类A class ConcreteColleagueA extends Colleague { send(event) receive(event) } note right of ConcreteColleagueA b具体同事类A/b -- 例如订单服务 只与中介者通信 end note 6. 具体同事类B class ConcreteColleagueB extends Colleague { send(event) receive(event) } note right of ConcreteColleagueB b具体同事类B/b -- 例如库存服务 只与中介者通信 end note 7. 关系连线 Colleague o-down- Mediator : 依赖 ConcreteMediator .up. Mediator : 实现 ConcreteColleagueA -up-| Colleague : 继承 ConcreteColleagueB -up-| Colleague : 继承 ConcreteMediator -- ConcreteColleagueA : 协调 ConcreteMediator -- ConcreteColleagueB : 协调 enduml 《Java 23 种设计模式从踩坑到精通》快速导航开篇系列介绍与目录正篇Mediator 中介者模式 —— 对象关系太乱请一位“中间人”当前番外 · 中介者模式 × 物流服务协调你在这里创建型模式汇总结构型模式汇总行为型模式汇总 关注《Java 23 种设计模式从踩坑到精通》用 25 篇文章彻底吃透设计模式。福利预告全系列代码及 UML 源码将在完结时统一打包开放点击「关注」「收藏」第一时间获取。 除了设计模式我也在深挖智能物流实战WMS、托盘调度、机器学习落地。欢迎点击头像看看专栏 《出版社物流WMS智能调度实战》、《电商多平台电子面单对接实战》。技术相通思路可鉴。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价