摘要

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

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. ✅ 中介者和观察者模式总结

目标

推荐模式

理由

统一控制业务流程

中介者模式

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

模块间异步通知

观察者模式

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

需要响应式扩展通知

观察者模式

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

模块依赖顺序较强

中介者模式

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

博文参考

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/83364.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/83364.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/83364.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

也说字母L:柔软的长舌

英语单词 tongue,意为“舌头” tongue n.舌,舌头;语言 很显然,“语言”是引申义,因为语言是抽象的,但舌头是具象的,根据由简入繁的原则,tongue显然首先是象形起义,表达…

性能测试实例(http和ldap协议压测)

一、某授权服务器生成授权码效率验证(http协议) 测试背景 在存量数据23万条的情况下,生成一条授权数据,需要10秒左右,用户反应数据生成效率太差,需要优化。初步判断是由于在授权数据生成时,有查…

Spring Boot中的事件与JMS消息集成

Spring Boot事件机制 Spring框架的事件处理是其核心特性之一,通过ApplicationEvent类和ApplicationListener接口实现。在Spring Boot应用中,事件机制是实现模块间消息传递的重要方式,通常用于业务逻辑内部通信。 内置事件类型 Spring应用上下文在启动时会触发多种内置事件…

第12次12: 修改和删除收货地址

第1步:在users应用下views.py中新增实现修改收货地址的视图类 class UpdateDestroyAddressView(LoginRequiredJSONMixin, View):def put(self, request, address_id):"""修改收货地址"""json_dict json.loads(request.body.decode(…

python常用库-pandas、Hugging Face的datasets库(大模型之JSONL(JSON Lines))

文章目录 python常用库pandas、Hugging Face的datasets库(大模型之JSONL(JSON Lines))背景什么是JSONL(JSON Lines)通过pandas读取和保存JSONL文件pandas读取和保存JSONL文件 Hugging Face的datasets库Hugg…

【论文笔记】SecAlign: Defending Against Prompt Injection with Preference Optimization

论文信息 论文标题:SecAlign: Defending Against Prompt Injection with Preference Optimization - CCS 25 论文作者: Sizhe Chen - UC Berkeley ;Meta, FAIR 论文链接:https://arxiv.org/abs/2410.05451 代码链接:h…

NLP学习路线图(十六):N-gram模型

一、为何需要语言模型?概率视角下的语言本质 自然语言处理的核心挑战在于让机器“理解”人类语言。这种理解的一个关键方面是处理语言的歧义性、创造性和结构性。语言模型(Language Model, LM)为此提供了一种强大的数学框架:它赋…

HTML 中 class 属性介绍、用法

1、🔖 什么是 class class 是 HTML 元素的一个核心属性,用来为元素指定一个或多个类名。它在网页开发中承担三大作用: 🎨 连接样式(CSS):让元素应用预定义的视觉效果⚙️ 绑定行为&#xff08…

MybatisPlus(含自定义SQL、@RequiredArgsConstructor、静态工具类Db)

大家在日常开发中应该能发现,单表的CRUD功能代码重复度很高,也没有什么难度。而这部分代码量往往比较大,开发起来比较费时。 因此,目前企业中都会使用一些组件来简化或省略单表的CRUD开发工作。目前在国内使用较多的一个组件就是…

信贷风控规则策略累计增益lift测算

在大数据风控业务实践过程中,目前业内主要还是采用规则叠加的办法做策略,但是会遇到一些问题: 1.我们有10条规则,我上了前7条后,后面3条的绝对风险增益是多少? 2.我的规则之间应该做排序吗,最重…

Python窗体编程技术详解

文章目录 1. Tkinter简介示例代码优势劣势 2. PyQt/PySide简介示例代码(PyQt5)优势劣势 3. wxPython简介示例代码优势劣势 4. Kivy简介示例代码优势劣势 5. PySimpleGUI简介示例代码优势劣势 技术对比总结选择建议 Python提供了多种实现图形用户界面(GUI)编程的技术&#xff0c…

Linux 操作系统安装及基本使用

Linux 操作系统安装及基本使用 在信息技术飞速发展的今天,Linux 操作系统凭借其开源、高性能、稳定性强等优势,在服务器、云计算、嵌入式等领域占据着重要地位。本文将详细介绍如何在 VMware 虚拟机下安装 Linux 系统(以 CentOS 为例&#x…

Python数学可视化——显函数、隐函数及复杂曲线的交互式绘图技术

Python数学可视化——显函数、隐函数及复杂曲线的交互式绘图技术 一、引言 在科学计算和数据分析中,函数与方程的可视化是理解数学关系和物理现象的重要工具。本文基于Python的Tkinter和Matplotlib库,实现一个功能完善的函数与方程可视化工具&#xff…

【MySQL基础】库的操作:创建、删除与管理数据库

MySQL学习: https://blog.csdn.net/2301_80220607/category_12971838.html?spm1001.2014.3001.5482 前言: 在上一篇我们已经讲解了数据库的基本内容,相信大家对数据库已经有了一些自己的理解,从这篇开始我们就开始正式进入如何…

Linux服务器系统配置初始化脚本

服务器系统配置初始化脚本 #!/bin/bash set -euo pipefail # 安全设置:遇错退出、未定义变量报错、管道错误处理# 设置时区并同步时间 timedatectl set-timezone Asia/Shanghai >/dev/null || ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime# 安装c…

Milvus单机模式安装和试用

1.安装ollama的package包; # install package pip install -U langchain-ollama2.我们直接使用ChatOllama实例化模型,并通过invoke进行调用; from langchain_ollama import ChatOllamallm ChatOllama(model"deepseek-r1") messa…

秒出PPT正式改名秒出AI,开启AI赋能新体验!

在现代办公环境中,借助智能工具提升工作效率已经成为趋势。秒出AI作为一款集AI PPT制作、动画、巨幕、视频、设计以及智能简历功能于一体的综合办公平台,为用户提供一站式智能内容生成解决方案,极大地简化了内容创作流程。 1. AI驱动的一键P…

Rust 学习笔记:发布一个 crate 到 crates.io

Rust 学习笔记:发布一个 crate 到 crates.io Rust 学习笔记:发布一个 crate 到 crates.io提供有用的文档注释常用标题文档注释作为测试注释所包含的项目 使用 pub use 导出一个方便的公共 API设置 crates.io 账户添加 metadata 到一个新的 crate发布到 c…

C++输入与输出技术详解

文章目录 引言一、C标准输入输出流1.1 cin与cout1.2 cerr与clog 二、C风格输入输出函数2.1 scanf与printf2.2 fgets与puts 三、输入输出优化四、总结 引言 在C编程中,输入与输出(I/O)操作是程序与用户、文件或其他系统组件交互的核心环节。C…

安全编码与AI接口权限控制

安全编码与AI接口权限控制 在AI系统中,模型服务的开放接口往往涉及敏感数据、核心算法与算力资源,如果缺乏有效的安全编码与权限控制机制,极易引发数据泄露、滥用调用或非法操作等问题。本节将从“接口安全策略”“权限验证流程”“Token管控机制”“多租户身份隔离”四个方…