大家好欢迎来到设计模式系列文章基础篇的第十九篇内容。在上一篇中我们学习了行为型模式的第八种常用模式——状态模式其核心是将对象的各类状态封装成独立的状态类让对象的行为跟随自身状态动态改变彻底消除冗余的状态判断分支完美解决状态与行为的耦合问题广泛应用于订单状态管理、设备状态控制等场景。今天我们将学习行为型模式的第九种常用模式——中介者模式它的核心是通过引入一个中介者对象封装多个对象之间的所有交互逻辑让原本相互依赖、形成网状结构的对象转变为通过中介者间接通信的星型结构彻底解耦对象间的直接依赖简化复杂对象间的交互关系提升代码的可维护性与扩展性。在日常开发和生活中中介者模式的场景随处可见比如公司的项目组多个开发人员、测试人员、产品经理之间无需直接沟通而是通过项目经理中介者传递信息、协调工作再比如聊天室系统多个用户之间发送消息无需直接建立连接而是通过服务器中介者转发消息还有GUI界面中的表单联动多个输入框、按钮、下拉框之间的交互通过一个中介者对象统一管理避免组件间相互引用导致的代码混乱。如果不使用中介者模式多个对象之间会形成复杂的网状依赖——每个对象都需要持有其他多个对象的引用才能完成交互这种方式会导致代码耦合度极高、可读性差、维护成本高。比如一个表单包含用户名、密码、验证码三个输入框和一个提交按钮若不使用中介者每个输入框都需要监听其他输入框的状态提交按钮也需要判断所有输入框的合法性新增输入框时需要修改所有相关组件的代码违背开闭原则。而中介者模式通过一个中介者对象统一管理所有组件的交互组件之间不再直接通信仅与中介者交互新增组件时只需修改中介者无需改动其他组件完美解决网状依赖的痛点。今天我们就从核心定义、结构、实战实现、场景对比、避坑指南全维度讲解帮大家彻底掌握这种“解耦网状依赖、简化交互”的实用设计模式。一、中介者模式的核心定义与设计初衷1. 核心定义中介者模式Mediator Pattern用一个中介者对象来封装一系列对象之间的交互使这些对象之间不再直接引用而是通过中介者间接通信。中介者负责协调各个对象之间的交互减少对象之间的耦合度使系统结构更清晰、更易于维护和扩展。中介者模式又称调停者模式核心是封装交互、解耦依赖、统一协调。通俗理解中介者模式就像我们生活中的房产中介。买家和卖家之间无需直接沟通买家只需告诉中介者自己的购房需求卖家只需告诉中介者自己的房屋信息中介者负责匹配双方需求、传递信息、协调交易流程最终完成交易。买家和卖家之间完全解耦无需知道对方的存在所有交互都通过中介者完成既简化了双方的沟通成本又降低了彼此的依赖。2. 设计初衷解决的核心问题中介者模式的出现核心是解决“多对象交互导致的网状依赖、代码耦合过高”的痛点具体解决3个核心问题解耦对象间的网状依赖将多个对象之间的直接引用转变为通过中介者间接通信消除对象间的相互依赖简化系统结构简化对象交互逻辑将分散在各个对象中的交互逻辑统一封装到中介者中对象自身只需关注自身的核心业务逻辑无需关心与其他对象的交互提升代码可扩展性新增对象或修改交互逻辑时只需修改中介者无需改动其他对象符合开闭原则降低维护成本。3. 设计原则适配中介者模式作为经典行为型模式严格贴合面向对象设计核心原则是解决多对象交互依赖的最佳实践单一职责原则中介者负责统一协调对象间的交互逻辑每个具体对象只负责自身的核心业务逻辑职责单一便于维护和调试开闭原则新增对象或修改交互规则时只需新增具体对象类、修改中介者的协调逻辑无需改动其他现有对象扩展灵活无侵入迪米特法则最少知道原则每个对象只需知道中介者的存在无需知道其他对象的具体实现减少对象之间的交互次数降低耦合度。二、中介者模式的核心结构4个核心角色中介者模式的结构清晰核心包含4个角色各司其职、协同完成对象间的间接交互我们以“聊天室系统”为场景逐一拆解角色职责与交互逻辑1. 抽象中介者Mediator中介者模式的核心接口定义中介者协调各个同事对象的通用方法通常包含注册同事对象、转发消息等核心方法。抽象中介者屏蔽了具体中介者的实现细节让同事对象只需依赖抽象中介者无需依赖具体中介者。对应聊天室场景中的“聊天室接口”定义注册用户、转发消息的方法。2. 具体中介者Concrete Mediator实现抽象中介者接口维护所有同事对象的引用封装具体的交互协调逻辑。具体中介者接收某个同事对象发送的消息根据消息类型和内容转发给对应的同事对象完成对象间的间接交互。对应聊天室场景中的“具体聊天室”管理所有注册的用户转发用户发送的消息。3. 抽象同事Colleague所有具体同事对象的抽象父类或接口定义同事对象的通用方法持有抽象中介者的引用提供向中介者发送消息的方法。抽象同事让所有具体同事对象都能通过中介者进行通信统一同事对象的交互方式。对应聊天室场景中的“用户接口”定义发送消息、接收消息的方法。4. 具体同事Concrete Colleague实现抽象同事接口持有抽象中介者的引用实现自身的核心业务逻辑同时通过中介者向其他同事对象发送消息、接收中介者转发的消息。具体同事对象之间不直接通信所有交互都通过中介者完成。对应聊天室场景中的“具体用户”可以发送消息、接收其他用户通过聊天室转发的消息。核心关系总结抽象中介者定义协调规范具体中介者实现协调逻辑并管理同事对象抽象同事定义交互规范具体同事通过中介者完成间接通信。所有对象之间的交互都由中介者统一协调形成星型结构彻底消除网状依赖。三、中介者模式的核心逻辑与执行流程中介者模式的核心逻辑是“中介协调、间接通信、解耦依赖”标准执行流程分为五步全程无对象间直接引用逻辑闭环定义抽象中介者接口声明注册同事对象、转发消息等通用协调方法定义抽象同事接口声明发送消息、接收消息的方法持有抽象中介者引用实现具体中介者类维护同事对象集合实现注册、消息转发等协调逻辑实现具体同事类实现自身核心业务逻辑通过中介者发送消息接收中介者转发的消息客户端初始化创建具体中介者和具体同事对象将同事对象注册到中介者通过同事对象发送消息中介者协调转发完成间接交互。关键要点具体同事对象之间不直接引用所有消息都通过中介者转发中介者统一管理同事对象和交互逻辑同事对象只需关注自身业务无需关心其他同事的存在新增同事对象时只需注册到中介者无需修改其他同事和中介者的核心逻辑。四、中介者模式的实战实现聊天室场景我们以高频的聊天室系统为场景使用Java代码实现中介者模式模拟多个用户通过聊天室中介者发送、接收消息的完整流程用户之间不直接通信所有消息都通过聊天室转发直观体现中介者模式解耦网状依赖、简化交互的核心优势。场景说明聊天室具体中介者管理多个用户具体同事用户注册到聊天室后可以发送消息聊天室接收消息后转发给除发送者外的所有其他用户用户可以接收聊天室转发的其他用户的消息实现群聊功能。1. 第一步定义抽象中介者接口Mediator// 抽象中介者聊天室接口 public interface Mediator{// 注册同事对象用户 void registerColleague(Colleague colleague);// 转发消息接收某个用户的消息转发给其他用户 void relayMessage(Colleague sender, String message);}2. 第二步定义抽象同事接口Colleague// 抽象同事用户接口 public abstract class Colleague{// 持有抽象中介者引用 protected Mediator mediator;// 用户名区分不同用户 protected String username;// 构造方法初始化中介者和用户名 public Colleague(Mediator mediator, String username){this.mediatormediator;this.usernameusername;}// 发送消息通过中介者转发消息 public abstract void sendMessage(String message);// 接收消息接收中介者转发的消息 public abstract void receiveMessage(String sender, String message);}3. 第三步实现具体中介者类ChatRoomMediator// 具体中介者具体聊天室importjava.util.ArrayList;importjava.util.List;public class ChatRoomMediator implements Mediator{// 维护所有注册的用户同事对象 private ListColleaguecolleagueListnew ArrayList();Override public void registerColleague(Colleague colleague){// 将用户注册到聊天室避免重复注册if(!colleagueList.contains(colleague)){colleagueList.add(colleague);System.out.println(colleague.username 已加入聊天室);}}Override public void relayMessage(Colleague sender, String message){// 转发消息将发送者的消息转发给除发送者外的所有其他用户for(Colleague colleague:colleagueList){if(!colleague.equals(sender)){colleague.receiveMessage(sender.username, message);}}}}4. 第四步实现具体同事类UserColleague// 具体同事具体用户 public class UserColleague extends Colleague{// 继承父类构造方法初始化中介者和用户名 public UserColleague(Mediator mediator, String username){super(mediator, username);}Override public void sendMessage(String message){System.out.println(\n username 发送消息 message);// 通过中介者转发消息 mediator.relayMessage(this, message);}Override public void receiveMessage(String sender, String message){// 接收中介者转发的消息 System.out.println(username 收到 sender 的消息 message);}}5. 第五步客户端测试// 客户端测试聊天室群聊场景 public class MediatorPatternTest{public static void main(String[]args){//1. 创建具体中介者聊天室 Mediator chatRoomnew ChatRoomMediator();//2. 创建具体同事用户并注册到聊天室 Colleague user1new UserColleague(chatRoom,张三);Colleague user2new UserColleague(chatRoom,李四);Colleague user3new UserColleague(chatRoom,王五);chatRoom.registerColleague(user1);chatRoom.registerColleague(user2);chatRoom.registerColleague(user3);//3. 模拟用户发送消息测试中介者转发功能 user1.sendMessage(大家好我是张三);user2.sendMessage(你好张三我是李四~);user3.sendMessage(欢迎大家加入聊天室);}}运行结果张三已加入聊天室 李四已加入聊天室 王五已加入聊天室 张三发送消息大家好我是张三 李四收到张三的消息大家好我是张三 王五收到张三的消息大家好我是张三 李四发送消息你好张三我是李四~ 张三收到李四的消息你好张三我是李四~ 王五收到李四的消息你好张三我是李四~ 王五发送消息欢迎大家加入聊天室 张三收到王五的消息欢迎大家加入聊天室 李四收到王五的消息欢迎大家加入聊天室从运行结果可以看出三个用户之间没有直接引用所有消息都通过聊天室中介者转发新增用户时只需创建用户对象并注册到聊天室无需修改其他用户的代码完美实现了解耦简化了用户间的交互逻辑。五、中介者模式的高频应用场景中介者模式适用于所有多个对象之间存在复杂交互、形成网状依赖的业务场景核心作用是解耦依赖、统一协调以下是四大高频落地场景1. 多组件交互场景最经典应用GUI界面、前端组件、后端服务间的多组件交互通过中介者统一协调避免组件间直接依赖表单联动页面中的多个输入框、按钮、下拉框之间的联动逻辑通过中介者统一管理比如用户名输入完成后自动校验并触发密码输入框的状态变化前端组件通信Vue、React等前端框架中多个组件之间的通信通过中介者如EventBus转发事件避免组件间层层传递props后端服务协调微服务架构中多个微服务之间的交互通过API网关中介者统一转发请求、协调服务调用避免服务间直接调用形成网状依赖。2. 消息转发场景需要将一个对象的消息转发给多个其他对象的场景通过中介者统一转发简化消息传递逻辑聊天室、群聊系统多个用户之间的消息传递通过服务器中介者转发无需用户间直接建立连接消息通知系统系统中的通知消息通过通知中介者转发给所有订阅该通知的用户或服务简化通知分发逻辑。3. 团队/流程协调场景多个角色、多个环节之间的协调工作通过中介者统一调度提升协作效率项目管理系统项目经理中介者协调开发、测试、产品、设计等多个角色的工作传递需求、反馈问题避免角色间直接沟通的混乱工作流审批系统审批中介者协调发起者、审批人、抄送人之间的交互统一管理审批流程传递审批意见和状态。4. 框架底层与工具类设计主流开源框架和工具类中大量使用中介者模式实现组件解耦与交互协调Spring Cloud API网关作为中介者统一接收客户端请求转发给对应的微服务协调微服务间的调用解耦客户端与微服务EventBus事件总线作为中介者管理事件的发布与订阅组件通过EventBus发送和接收事件无需直接引用Java Swing/AWTGUI组件之间的交互通过事件调度线程中介者统一处理事件避免组件间直接依赖。六、中介者模式 vs 观察者模式重点区分中介者模式与观察者模式都属于行为型模式都涉及多对象间的交互但核心目标、交互方式、依赖关系完全不同极易混淆通过表格清晰对比帮大家快速区分对比维度中介者模式观察者模式核心目标解耦多个对象之间的网状依赖通过中介者统一协调交互实现对象间的一对多依赖当主题变化时通知所有观察者交互方式双向交互对象通过中介者发送消息也通过中介者接收其他对象的消息单向交互只有主题向观察者发送通知观察者不向主题反馈依赖关系所有对象都依赖中介者对象之间无直接依赖形成星型结构观察者依赖主题主题不依赖观察者形成一对多的树形结构核心逻辑中介者封装交互逻辑协调多个对象之间的通信主题维护观察者列表状态变化时通知所有观察者更新适用场景多对象间存在复杂交互、形成网状依赖需要统一协调一个对象变化需要多个对象同步更新实现数据同步一句话总结中介者模式是“多对象交互靠中介解耦网状依赖”观察者模式是“一对象变化通知多对象实现数据同步”多对象相互交互用中介者模式一对象带动多对象更新用观察者模式。七、中介者模式的常见坑与避坑指南坑1中介者职责过重成为“上帝对象”中介者模式的核心是封装交互逻辑但如果所有交互逻辑都集中到中介者中会导致中介者类过于庞大、职责过重成为“上帝对象”难以维护和扩展。避坑指南拆分中介者职责将不同类型的交互逻辑拆分到多个子中介者中再通过一个顶层中介者协调子中介者中介者只负责协调交互不实现具体业务逻辑具体业务逻辑仍由同事对象实现。坑2过度使用中介者导致简单逻辑复杂化部分开发者在对象间交互简单、仅存在少量依赖的场景中强行使用中介者模式新增抽象中介者、具体中介者、抽象同事等角色导致代码冗余、逻辑复杂化违背设计模式的初衷。避坑指南只有当多个对象之间形成复杂的网状依赖、交互逻辑分散时才使用中介者模式对象间交互简单、依赖关系清晰时直接通过对象间引用交互即可无需过度设计。坑3同事对象与中介者耦合过高难以扩展部分开发者在实现时让同事对象直接依赖具体中介者而非抽象中介者导致新增中介者实现时需要修改所有同事对象的代码违背开闭原则。避坑指南同事对象只依赖抽象中介者接口不依赖具体中介者实现通过依赖注入的方式注入具体中介者降低同事对象与中介者的耦合度便于扩展。坑4忽略同事对象的注册与注销导致内存泄漏中介者会持有所有同事对象的引用如果同事对象不再使用时未从中介者中注销会导致同事对象无法被垃圾回收引发内存泄漏。避坑指南在同事对象生命周期结束时调用中介者的注销方法将同事对象从中介者的集合中移除定期清理中介者中无效的同事对象避免内存泄漏。坑5中介者处理消息转发效率过低当同事对象数量过多时中介者转发消息时遍历所有同事对象会导致消息转发效率过低影响系统性能。避坑指南对同事对象进行分组管理中介者根据消息类型只转发给对应分组的同事对象避免遍历所有同事使用异步转发机制避免消息转发阻塞主流程。八、系列文章预告本篇文章我们详细讲解了中介者模式的核心定义、四大核心角色、标准执行流程、聊天室场景实战代码、高频应用场景和避坑指南同时清晰区分了易混淆的观察者模式。中介者模式凭借“封装交互、解耦网状依赖、统一协调”的优势成为多对象复杂交互场景的首选设计模式能大幅简化系统结构、提升代码的可维护性与扩展性。下一篇我们将学习行为型模式的第十种常用模式——观察者模式它的核心是定义对象间的一对多依赖关系当一个对象主题的状态发生变化时所有依赖它的对象观察者都会自动收到通知并更新广泛应用于消息通知、数据同步、事件监听等场景是实现“发布-订阅”模式的核心思想。观察者模式——发布订阅解耦实现状态同步通知。我们不见不散