设计模式——中介者设计模式(行为型)
摘要
文章详细介绍了中介者设计模式,这是一种行为型设计模式,通过中介者对象封装多个对象间的交互,降低系统耦合度。文中阐述了其核心角色、优缺点、适用场景,并通过类图、时序图、实现方式、实战示例等多方面进行讲解,还探讨了与其他设计模式的组合使用,帮助读者全面理解该模式。
1. 中介者设计模式定义
中介者设计模式(Mediator Pattern)是一种行为型设计模式,它通过引入一个中介对象来封装多个对象之间的交互,从而使对象之间不再互相引用,降低系统的耦合度,让对象之间的通信通过中介者统一协调。
飞机起降管控系统:多架飞机(同事对象)之间不能自己协调起降,必须通过“塔台”(中介者)统一调度,这样飞机之间不需要知道彼此,只需与塔台通信。
1.1. 📌 核心角色
角色
说明
Mediator
抽象中介者,定义对象之间通信的接口
ConcreteMediator
具体中介者,实现协调各组件之间的交互逻辑
Colleague
同事类,每个与其他对象通信的对象,只与中介者通信
1.2. ✅ 优点
- 降低对象之间的耦合,避免“网状结构”,变为“星型结构”
- 交互集中管理,逻辑清晰、易维护
- 更易于扩展和修改通信规则
1.3. ❌ 缺点
- 中介者可能变得非常复杂,成为“上帝类”
- 不适合同事对象数量很少、交互简单的情况
1.4. ✅ 适用场景
- 多个对象之间存在复杂交互,导致系统结构混乱
- 希望将对象间的通信行为提取到一个独立类中进行管理
- 界面组件交互(如按钮、输入框等)、聊天系统、协作系统
2. 中介者设计模式结构
- 组件 (Component) 是各种包含业务逻辑的类。 每个组件都有一个指向中介者的引用, 该引用被声明为中介者接口类型。 组件不知道中介者实际所属的类, 因此你可通过将其连接到不同的中介者以使其能在其他程序中复用。
- 中介者 (Mediator) 接口声明了与组件交流的方法, 但通常仅包括一个通知方法。 组件可将任意上下文 (包括自己的对象) 作为该方法的参数, 只有这样接收组件和发送者类之间才不会耦合。
- 具体中介者 (Concrete Mediator) 封装了多种组件间的关系。 具体中介者通常会保存所有组件的引用并对其进行管理, 甚至有时会对其生命周期进行管理。
2.1. 中介者模式类图
2.2. 中介者模式时序图
3. 中介者设计模式实现方式
中介者设计模式是一种行为型设计模式,通过引入中介对象封装多个对象之间的交互,从而使对象之间不再互相引用,达到松耦合的目的。
3.1. 🧱 核心实现结构
3.1.1. 抽象中介者接口(Mediator
)
定义统一的通信接口,用于同事对象之间的协调。
public interface Mediator { void notify(String event, Colleague sender);}
3.1.2. 抽象同事类(Colleague
)
每个同事类都持有中介者的引用,只与中介者通信。
public abstract class Colleague { protected Mediator mediator; public Colleague(Mediator mediator) { this.mediator = mediator; }}
3.1.3. 具体同事类(ConcreteColleague
)
具体的业务类,通过调用中介者来进行通信。
public class ConcreteColleagueA extends Colleague { public ConcreteColleagueA(Mediator mediator) { super(mediator); } public void doSomething() { System.out.println(\"ColleagueA 执行操作,通知中介者\"); mediator.notify(\"A完成\", this); } public void receive(String msg) { System.out.println(\"ColleagueA 收到消息:\" + msg); }}
public class ConcreteColleagueB extends Colleague { public ConcreteColleagueB(Mediator mediator) { super(mediator); } public void doSomething() { System.out.println(\"ColleagueB 执行操作,通知中介者\"); mediator.notify(\"B完成\", this); } public void receive(String msg) { System.out.println(\"ColleagueB 收到消息:\" + msg); }}
3.1.4. 具体中介者类(ConcreteMediator
)
负责协调同事类之间的通信逻辑。
public class ConcreteMediator implements Mediator { private ConcreteColleagueA colleagueA; private ConcreteColleagueB colleagueB; public void setColleagueA(ConcreteColleagueA a) { this.colleagueA = a; } public void setColleagueB(ConcreteColleagueB b) { this.colleagueB = b; } @Override public void notify(String event, Colleague sender) { if (sender == colleagueA) { colleagueB.receive(\"来自A的通知:\" + event); } else if (sender == colleagueB) { colleagueA.receive(\"来自B的通知:\" + event); } }}
3.2. 🛠 测试用例
public class Main { public static void main(String[] args) { ConcreteMediator mediator = new ConcreteMediator(); ConcreteColleagueA a = new ConcreteColleagueA(mediator); ConcreteColleagueB b = new ConcreteColleagueB(mediator); mediator.setColleagueA(a); mediator.setColleagueB(b); a.doSomething(); b.doSomething(); }}
3.3. ✅ 输出示例
ColleagueA 执行操作,通知中介者ColleagueB 收到消息:来自A的通知:A完成ColleagueB 执行操作,通知中介者ColleagueA 收到消息:来自B的通知:B完成
3.4. 🧩 中介者示例总结
角色
职责
Mediator
定义中介者接口,协调同事之间的通信
ConcreteMediator
持有所有同事的引用,封装对象间交互逻辑
Colleague
持有中介者引用,通过中介者与其他对象交互,不直接引用其他对象
应用价值
解耦多个对象间复杂的网状关系,转化为中心化的星型结构,便于扩展和维护
4. 中介者设计模式适合场景
4.1. ✅ 中介者设计模式适合场景
场景描述
说明
多个对象间复杂交互
对象之间交互关系复杂且频繁,使用中介者简化对象间直接通信
需要解耦对象之间的依赖
通过中介者集中管理,减少对象之间的耦合,符合单一职责原则
系统中的对象之间通信逻辑经常变化
中介者封装交互逻辑,修改交互规则只需改中介者,不用改对象
多个模块协作实现复杂业务流程
中介者协调不同模块协作,避免各模块直接耦合
需要统一管理和监控对象间通信
中介者作为统一中心,便于增加日志、监控、事务控制等功能
4.2. ❌ 中介者设计模式不适合场景
对象间通信关系简单,耦合不明显
使用中介者会增加不必要的复杂度,直接通信更清晰简单
对象数量非常少
中介者的抽象和管理成本超过了实际收益
性能要求极高,不允许通信中间层增加延迟
中介者引入了额外的转发和协调,可能导致一定的性能损耗
系统逻辑对对象的独立性和自治性要求较高
中介者集中控制会限制对象自治,增加耦合
需要灵活、动态调整对象间通信方式
中介者模式较为静态,频繁调整通信机制可能导致中介者复杂难维护
5. 中介者设计模式实战示例
下面给你一个基于Spring框架,使用注解注入,非构造函数注入的中介者设计模式实战示例,场景是简化版金融风控系统中多个风控模块(比如信用评分模块、额度计算模块)之间的协作。
5.1. 设计思路
- 中介者接口:定义协调各风控模块交互的方法
- 具体中介者类:实现接口,注入各风控模块,协调调用
- 风控模块接口:所有风控模块统一接口
- 具体风控模块实现类:业务模块实现
5.2. 中介者接口
public interface RiskMediator { void execute(String action);}
5.3. 风控模块接口
public interface RiskModule { void check();}
5.4. 具体风控模块实现
import org.springframework.stereotype.Component;@Componentpublic class CreditScoreModule implements RiskModule { @Override public void check() { System.out.println(\"信用评分模块风控校验...\"); }}@Componentpublic class CreditLimitModule implements RiskModule { @Override public void check() { System.out.println(\"额度计算模块风控校验...\"); }}
5.5. 具体中介者实现(协调模块)
import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;@Componentpublic class RiskMediatorImpl implements RiskMediator { // 非构造函数注入 @Autowired private CreditScoreModule creditScoreModule; @Autowired private CreditLimitModule creditLimitModule; @Override public void execute(String action) { switch (action) { case \"creditCheck\": creditScoreModule.check(); break; case \"limitCheck\": creditLimitModule.check(); break; case \"allCheck\": creditScoreModule.check(); creditLimitModule.check(); break; default: System.out.println(\"未知操作\"); } }}
5.6. 业务调用示例(Service)
import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;@Servicepublic class RiskService { @Autowired private RiskMediator riskMediator; public void performRiskCheck() { System.out.println(\"开始风控校验...\"); riskMediator.execute(\"allCheck\"); System.out.println(\"风控校验完成\"); }}
5.7. Spring Boot 主程序测试
import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.CommandLineRunner;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class RiskControlApplication implements CommandLineRunner { @Autowired private RiskService riskService; public static void main(String[] args) { SpringApplication.run(RiskControlApplication.class, args); } @Override public void run(String... args) throws Exception { riskService.performRiskCheck(); }}
5.8. 运行结果
复制编辑开始风控校验...信用评分模块风控校验...额度计算模块风控校验...风控校验完成
说明
- 中介者对象负责协调多个风控模块,调用对应方法完成协作。
- 如果以后需要新增风控模块,只需在中介者类中添加对应依赖并扩展
execute
方法即可。 - 解耦风控模块之间的直接调用,实现灵活协作。
6. 中介者设计模式思考
6.1. 中介者设计模式常和以下设计模式组合使用,提升系统解耦性、灵活性和可维护性?
设计模式
作用
组合理由
观察者模式
事件通知,模块状态变更监听
松耦合,异步通知
策略模式
不同处理策略动态切换
灵活行为管理
命令模式
请求封装,支持撤销、排队
请求管理解耦
责任链模式
按顺序处理请求
流程控制与模块责任划分
工厂模式
创建模块实例
解耦模块实例化
状态模式
根据状态改变行为
简化状态管理,增强灵活性
6.1.1. 观察者模式(Observer Pattern)
- 场景:中介者作为事件中心,监听模块状态变化并通知相关模块。
- 组合效果:模块状态变化由中介者发起事件通知,避免模块间直接依赖,实现松耦合。
6.1.2. 策略模式(Strategy Pattern)
- 场景:中介者根据不同场景或条件,动态选择不同的处理策略。
- 组合效果:中介者协调不同策略,提升行为灵活性和可扩展性。
6.1.3. 命令模式(Command Pattern)
- 场景:将请求封装成命令对象,中介者负责调用命令,支持请求排队、撤销等操作。
- 组合效果:使请求调用和执行解耦,中介者集中管理命令执行。
6.1.4. 责任链模式(Chain of Responsibility Pattern)
- 场景:多个模块按顺序处理请求,中介者组织责任链,协调链上的处理步骤。
- 组合效果:流程化请求处理,增强模块间协作的灵活控制。
6.1.5. 工厂模式(Factory Pattern)
- 场景:中介者创建或获取模块实例,通过工厂解耦模块创建细节。
- 组合效果:提高模块实例管理灵活性,便于模块替换和扩展。
6.1.6. 状态模式(State Pattern)
- 场景:中介者根据系统或模块状态变化,动态调整模块行为。
- 组合效果:将状态和行为分离,简化中介者的决策逻辑。
6.2. 中介者和观察者模式实战示例
6.2.1. 适用场景对比
模式
适用场景
特点
中介者模式
多个组件之间复杂协作、行为依赖,强交互逻辑需要统一协调
强中心化,便于流程控制、逻辑清晰,但中介者本身易变复杂
观察者模式
一个对象状态变化需通知多个对象,多个模块监听某事件或行为
弱耦合、支持异步,适合事件驱动架构,但流程控制不集中,追踪困难
6.2.2. ✅ 场景 1:金融风控审批系统(使用中介者模式)
业务背景: 用户提交贷款申请,需依次经过以下模块:
- 黑名单检查
- 身份实名认证
- 反欺诈评分
- 授信额度计算
这些模块相互有顺序依赖,并存在交互控制。
✅ 实现方式(中介者模式):
@Componentpublic class RiskMediator { @Autowired private BlacklistChecker blacklistChecker; @Autowired private IdentityVerifier identityVerifier; @Autowired private AntiFraudEngine antiFraudEngine; @Autowired private CreditScoreCalculator creditScoreCalculator; public RiskResult process(UserApplyDTO apply) { if (!blacklistChecker.check(apply)) return RiskResult.reject(\"黑名单\"); if (!identityVerifier.verify(apply)) return RiskResult.reject(\"身份校验失败\"); FraudResult fraud = antiFraudEngine.analyze(apply); if (fraud.isHighRisk()) return RiskResult.reject(\"欺诈嫌疑\"); return creditScoreCalculator.calculate(apply); }}
所有风控组件之间不直接通信,由 RiskMediator
协调。
6.2.3. ✅ 场景 2:用户注册发送通知(使用观察者模式)
业务背景: 用户注册成功后,需要:
- 发送欢迎短信
- 推送用户画像同步任务
- 发放注册优惠券
这三个操作彼此独立,不影响主流程。
✅ 实现方式(观察者模式 + Spring Event):
定义事件对象:
public class UserRegisterEvent extends ApplicationEvent { private final Long userId; public UserRegisterEvent(Object source, Long userId) { super(source); this.userId = userId; } public Long getUserId() { return userId; }}
发布事件:
@Componentpublic class UserService { @Autowired private ApplicationEventPublisher publisher; public void register(UserDTO dto) { // 注册逻辑... publisher.publishEvent(new UserRegisterEvent(this, dto.getId())); }}
监听器(观察者):
@Componentpublic class WelcomeSmsListener { @EventListener public void onRegister(UserRegisterEvent event) { // 发送短信 }}@Componentpublic class ProfileSyncListener { @EventListener public void onRegister(UserRegisterEvent event) { // 同步画像 }}
Spring 自动管理监听器注册,模块间完全解耦,扩展方便。
6.3. ✅ 中介者和观察者模式总结
目标
推荐模式
理由
统一控制业务流程
中介者模式
控制逻辑集中,适合复杂流程协调
模块间异步通知
观察者模式
低耦合、事件驱动、支持多个订阅方
需要响应式扩展通知
观察者模式
任意监听器可接入或移除,灵活扩展
模块依赖顺序较强
中介者模式
控制好执行顺序,模块逻辑依赖清晰