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

设计模式——中介者设计模式(行为型)

摘要

文章详细介绍了中介者设计模式,这是一种行为型设计模式,通过中介者对象封装多个对象间的交互,降低系统耦合度。文中阐述了其核心角色、优缺点、适用场景,并通过类图、时序图、实现方式、实战示例等多方面进行讲解,还探讨了与其他设计模式的组合使用,帮助读者全面理解该模式。

1. 中介者设计模式定义

中介者设计模式(Mediator Pattern)是一种行为型设计模式,它通过引入一个中介对象来封装多个对象之间的交互,从而使对象之间不再互相引用,降低系统的耦合度,让对象之间的通信通过中介者统一协调。

飞机起降管控系统:多架飞机(同事对象)之间不能自己协调起降,必须通过“塔台”(中介者)统一调度,这样飞机之间不需要知道彼此,只需与塔台通信。

1.1. 📌 核心角色

角色

说明

Mediator

抽象中介者,定义对象之间通信的接口

ConcreteMediator

具体中介者,实现协调各组件之间的交互逻辑

Colleague

同事类,每个与其他对象通信的对象,只与中介者通信

1.2. ✅ 优点

  • 降低对象之间的耦合,避免“网状结构”,变为“星型结构”
  • 交互集中管理,逻辑清晰、易维护
  • 更易于扩展和修改通信规则

1.3. ❌ 缺点

  • 中介者可能变得非常复杂,成为“上帝类”
  • 不适合同事对象数量很少、交互简单的情况

1.4. ✅ 适用场景

  • 多个对象之间存在复杂交互,导致系统结构混乱
  • 希望将对象间的通信行为提取到一个独立类中进行管理
  • 界面组件交互(如按钮、输入框等)、聊天系统、协作系统

2. 中介者设计模式结构

  1. 组件 (Component) 是各种包含业务逻辑的类。 每个组件都有一个指向中介者的引用, 该引用被声明为中介者接口类型。 组件不知道中介者实际所属的类, 因此你可通过将其连接到不同的中介者以使其能在其他程序中复用。
  2. 中介者 (Mediator) 接口声明了与组件交流的方法, 但通常仅包括一个通知方法。 组件可将任意上下文 (包括自己的对象) 作为该方法的参数, 只有这样接收组件和发送者类之间才不会耦合。
  3. 具体中介者 (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;}@Overridepublic 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;@Component
public class CreditScoreModule implements RiskModule {@Overridepublic void check() {System.out.println("信用评分模块风控校验...");}
}@Component
public class CreditLimitModule implements RiskModule {@Overridepublic void check() {System.out.println("额度计算模块风控校验...");}
}

5.5. 具体中介者实现(协调模块)

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class RiskMediatorImpl implements RiskMediator {// 非构造函数注入@Autowiredprivate CreditScoreModule creditScoreModule;@Autowiredprivate CreditLimitModule creditLimitModule;@Overridepublic 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;@Service
public class RiskService {@Autowiredprivate 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;@SpringBootApplication
public class RiskControlApplication implements CommandLineRunner {@Autowiredprivate RiskService riskService;public static void main(String[] args) {SpringApplication.run(RiskControlApplication.class, args);}@Overridepublic 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:金融风控审批系统(使用中介者模式)

业务背景: 用户提交贷款申请,需依次经过以下模块:

  • 黑名单检查
  • 身份实名认证
  • 反欺诈评分
  • 授信额度计算
    这些模块相互有顺序依赖,并存在交互控制。

✅ 实现方式(中介者模式):

@Component
public 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; }
}

发布事件:

@Component
public class UserService {@Autowired private ApplicationEventPublisher publisher;public void register(UserDTO dto) {// 注册逻辑...publisher.publishEvent(new UserRegisterEvent(this, dto.getId()));}
}

监听器(观察者):

@Component
public class WelcomeSmsListener {@EventListenerpublic void onRegister(UserRegisterEvent event) {// 发送短信}
}@Component
public class ProfileSyncListener {@EventListenerpublic void onRegister(UserRegisterEvent event) {// 同步画像}
}

Spring 自动管理监听器注册,模块间完全解耦,扩展方便。

6.3. ✅ 中介者和观察者模式总结

目标

推荐模式

理由

统一控制业务流程

中介者模式

控制逻辑集中,适合复杂流程协调

模块间异步通知

观察者模式

低耦合、事件驱动、支持多个订阅方

需要响应式扩展通知

观察者模式

任意监听器可接入或移除,灵活扩展

模块依赖顺序较强

中介者模式

控制好执行顺序,模块逻辑依赖清晰

博文参考

相关文章:

  • Git GitHub Gitee
  • github 2FA双重认证丢失解决
  • SQL Transactions(事务)、隔离机制
  • 【C语言预处理详解(下)】--#和##运算符,命名约定,命令行定义 ,#undef,条件编译,头文件的包含,嵌套文件包含,其他预处理指令
  • PyTorch——卷积操作(2)
  • TomatoSCI数据分析实战:探索社交媒体成瘾
  • Hadoop 大数据启蒙:深入解析分布式基石 HDFS
  • JSP、HTML和Tomcat
  • Vue-5-基于JavaScript和plotly.js绘制数据分析类图表
  • pytorch基本运算-范数
  • TS 星际通信指南:从 TCP 到 UDP 的宇宙漫游
  • 初识CSS3
  • Pytorch知识点2
  • U-ResNet 改进:集成特征金字塔网络(FPN)
  • 深度学习与神经网络 前馈神经网络
  • vue中父子参数传递双向的方式不同
  • 聚类分析 | MATLAB实现基于SOM自组织特征映射聚类可视化
  • react 生命周期
  • 详解鸿蒙仓颉开发语言中的计时器
  • LLM模型量化从入门到精通:Shrink, Speed, Repeat
  • 免费java我的世界/优化资源配置
  • 网站建设和编程/新产品市场推广方案
  • 设计师个人网站/找个网站
  • 做淘宝客需要建网站吗/九易建网站的建站流程
  • 从化网站开发/网络营销策划书2000字
  • 动态网站的例子/百度官方网站登录