中介者模式:解耦对象间复杂交互的设计模式

中介者模式:解耦对象间复杂交互的设计模式

一、模式核心:用中介者统一管理对象交互,避免两两直接依赖

当系统中多个对象之间存在复杂的网状交互时(如 GUI 界面中按钮、文本框、下拉框的联动),对象间直接调用会导致关系混乱、难以维护。

中介者模式(Mediator Pattern) 通过引入一个中介者对象(Mediator),将对象间的直接交互转换为与中介者的单向交互。所有对象只需与中介者通信,由中介者协调处理交互逻辑,从而实现对象间的松耦合。核心解决:

  • 交互复杂性:避免对象间形成复杂的依赖网络,降低系统复杂度。
  • 可维护性:交互逻辑集中在中介者中,修改时只需调整中介者,无需修改多个对象。
  • 扩展性:新增对象时只需实现与中介者的交互,不影响现有对象间的逻辑。

核心思想与 UML 类图

中介者模式包含以下角色:

  1. 中介者接口(Mediator):定义对象间交互的接口,如接收消息、分发消息。
  2. 具体中介者(Concrete Mediator):实现中介者接口,协调具体同事对象的交互。
  3. 同事类(Colleague):依赖中介者,通过中介者间接交互,不直接调用其他同事。

PlantUML Diagram

二、核心实现:GUI 界面组件的交互协调

1. 定义中介者接口

public interface Mediator {  void notify(Object sender, String event); // 接收消息(发送者、事件类型)  
}  

2. 实现具体中介者(处理组件联动)

public class UIMediator implements Mediator {  private Button button;  private TextBox textBox;  private Dropdown dropdown;  // 设置中介者关联的组件  public void setButton(Button button) {  this.button = button;  }  public void setTextBox(TextBox textBox) {  this.textBox = textBox;  }  public void setDropdown(Dropdown dropdown) {  this.dropdown = dropdown;  }  @Override  public void notify(Object sender, String event) {  if (sender == button && "click".equals(event)) {  // 按钮点击时,获取文本框内容并更新下拉框  String text = textBox.getText();  dropdown.setSelectedItem(text);  System.out.println("按钮点击:设置下拉框选项为 " + text);  } else if (sender == dropdown && "select".equals(event)) {  // 下拉框选择时,清空文本框  textBox.clear();  System.out.println("下拉框选择:清空文本框");  }  }  
}  

3. 定义抽象同事类(组件基类)

public abstract class UIComponent {  protected Mediator mediator;  public void setMediator(Mediator mediator) {  this.mediator = mediator;  }  protected void sendEvent(String event) {  if (mediator != null) {  mediator.notify(this, event); // 通过中介者发送事件  }  }  
}  

4. 实现具体同事类(按钮、文本框、下拉框)

按钮组件
public class Button extends UIComponent {  public void onClick() {  System.out.println("按钮被点击");  sendEvent("click"); // 发送点击事件给中介者  }  
}  
文本框组件
public class TextBox extends UIComponent {  private String text;  public String getText() {  return text;  }  public void setText(String text) {  this.text = text;  }  public void clear() {  text = "";  System.out.println("文本框已清空");  }  
}  
下拉框组件
public class Dropdown extends UIComponent {  private String selectedItem;  public void setSelectedItem(String item) {  this.selectedItem = item;  System.out.println("下拉框选中:" + selectedItem);  }  
}  

5. 客户端初始化中介者与组件

public class ClientDemo {  public static void main(String[] args) {  // 创建中介者和组件  UIMediator mediator = new UIMediator();  Button button = new Button();  TextBox textBox = new TextBox();  Dropdown dropdown = new Dropdown();  // 组件关联中介者  button.setMediator(mediator);  textBox.setMediator(mediator);  dropdown.setMediator(mediator);  // 中介者关联组件(双向绑定)  mediator.setButton(button);  mediator.setTextBox(textBox);  mediator.setDropdown(dropdown);  // 模拟用户操作:文本框输入内容,按钮点击触发联动  textBox.setText("Option A");  button.onClick(); // 按钮点击,通过中介者更新下拉框  System.out.println("\n模拟下拉框选择操作:");  mediator.notify(dropdown, "select"); // 下拉框选择,通过中介者清空文本框  }  
}  

输出结果

按钮被点击  
按钮点击:设置下拉框选项为 Option A  
下拉框选中:Option A  模拟下拉框选择操作:  
下拉框选择:清空文本框  
文本框已清空  

三、框架与源码中的中介者实践

1. Spring MVC 的 Controller 作为中介者

在 Spring MVC 中,Controller 作为中介者协调 ModelView 的交互:

  • View(如 JSP)发送请求到 Controller
  • Controller 调用 Model 处理业务逻辑,再将结果返回给 View
@Controller  
public class UserController {  @Autowired  private UserService userService; // Model 层  @GetMapping("/user/{id}")  public String getUser(@PathVariable int id, Model model) {  User user = userService.getUser(id);  model.addAttribute("user", user); // 中介者传递数据到 View  return "user.jsp"; // 中介者决定返回视图  }  
}  

2. Android 的 Activity 作为中介者

Android 中 Activity 作为中介者管理界面组件(ButtonEditText 等)的交互:

  • 组件通过 setOnClickListener 注册事件到 Activity
  • Activity 处理事件并协调组件状态更新。
public class MainActivity extends AppCompatActivity {  private EditText editText;  private TextView textView;  @Override  protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_main);  editText = findViewById(R.id.edit_text);  textView = findViewById(R.id.text_view);  findViewById(R.id.button).setOnClickListener(v -> {  String text = editText.getText().toString();  textView.setText("输入内容:" + text); // 中介者协调组件交互  });  }  
}  

3. Java Swing 的 Event Dispatch Thread

Swing 通过事件分发线程(中介者)处理组件事件,避免组件间直接通信:

  • 按钮点击事件由 Event Dispatch Thread 接收并分发给注册的监听器。

四、避坑指南:正确使用中介者模式的 3 个要点

1. 避免中介者过度复杂

若中介者承担过多职责,会形成 “上帝对象”。可将中介者拆分为多个专用中介者(如订单中介者、支付中介者),或引入分层结构(如中介者 + 协调者)。

2. 平衡中介者与同事的职责

同事类应尽量保持简单,仅包含自身状态和基本操作,复杂逻辑集中在中介者中。若同事类需要频繁调用中介者,需检查是否违反单一职责原则。

3. 区分中介者模式与观察者模式

  • 中介者模式:对象间通过中介者间接交互,形成星型结构(非广播式)。
  • 观察者模式:主题与观察者是一对多的依赖关系,观察者被动接收通知(广播式)。

六、总结:何时该用中介者模式?

适用场景核心特征典型案例
对象间网状交互多个对象间存在复杂直接调用GUI 界面组件联动、分布式系统节点通信
系统重构解耦遗留系统中对象间紧耦合,需简化依赖微服务间消息路由、legacy 系统改造
集中式逻辑管理需要将交互逻辑集中管理与维护工作流引擎、交易系统规则引擎

中介者模式通过 “中心化管理” 的设计,有效降低了对象间的耦合度,提升了系统的可维护性和扩展性。下一篇我们将探讨访问者模式,解析如何分离数据结构与操作,敬请期待!

扩展思考:中介者模式的缺点

  • 中介者单点风险:中介者故障会导致整个系统交互失效,需通过冗余设计或分布式中介者缓解。
  • 调试难度增加:交互逻辑集中在中介者中,需借助日志或调试工具追踪消息流程。

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

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

相关文章

豆包桌面版 1.47.4 可做浏览器,免安装绿色版

自己动手升级更新办法: 下载新版本后安装,把 C:\Users\用户名\AppData\Local\Doubao\Application 文件夹的文件,拷贝替换 DoubaoPortable\App\Doubao 文件夹的文件,就升级成功了。 再把安装的豆包彻底卸载就可以。 桌面版比网页版…

Android PackageManagerService(PMS)框架深度解析

目录 一、概念与核心作用 二、技术架构与模块组成 1. 分层架构 1.1 应用层架构细节 1.2 Binder接口层实现 1.3 PMS核心服务层 1.4 底层支持层实现 2. 核心模块技术要点与工作流程 2.1 PackageParser 2.2 Settings 2.3 PermissionManager 2.4 Installer 2.5 ComponentM…

TensorFlow深度学习实战(14)——循环神经网络详解

TensorFlow深度学习实战(14)——循环神经网络详解 0. 前言1. 基本循环神经网络单元1.1 循环神经网络工作原理1.2 时间反向传播1.3 梯度消失和梯度爆炸问题2. RNN 单元变体2.1 长短期记忆2.2 门控循环单元2.3 Peephole LSTM3. RNN 变体3.1 双向 RNN3.2 状态 RNN4. RNN 拓扑结构…

PySide6 GUI 学习笔记——常用类及控件使用方法(常用类矩阵QRectF)

文章目录 类描述构造方法主要方法1. 基础属性2. 边界操作3. 几何运算4. 坐标调整5. 转换方法6. 状态判断 类特点总结1. 浮点精度:2. 坐标系统:3. 有效性判断:4. 几何运算:5. 类型转换:6. 特殊处理: 典型应用…

Electron主进程渲染进程间通信的方式

在 Electron 中,主进程和渲染进程之间的通信主要通过 IPC(进程间通信)机制实现。以下是几种常见的通信方式: 1. 渲染进程向主进程发送消息(单向) 渲染进程可以通过 ipcRenderer.send 向主进程发送消息&am…

【C++基础知识】C++类型特征组合:`disjunction_v` 和 `conjunction_v` 深度解析

这两个模板是C17引入的类型特征组合工具,用于构建更复杂的类型判断逻辑。下面我将从技术实现到实际应用进行全面剖析: 一、基本概念与C引入版本 1. std::disjunction_v (逻辑OR) 引入版本:C17功能:对多个类型特征进行逻辑或运算…

私有知识库 Coco AI 实战(二):摄入 MongoDB 数据

在之前的文章中,我们介绍过如何使用《 Logstash 迁移 MongoDB 数据到 Easyseach》,既然 Coco AI 后台数据存储也使用 Easysearch,我们能否直接把 MongoDB 的数据迁移到 Coco AI 的 Easysearch,使用 Coco AI 对数据进行检索呢&…

sql server 与navicat测试后,连接qt

先用Navicat测试和sql的连通性,Navicat和sql连通之后,qt也能和sql连通了。 Navicat和Sqlserver Management 能连上,项目无法连接本地 Navicat 连接SQLServer 数据库 QT国内镜像网站 Navicat连接SqlServer的问题点 Sql Server的基本配置以及使…

2025年3月电子学会青少年机器人技术(六级)等级考试试卷-理论综合

青少年机器人技术等级考试理论综合试卷(六级) 分数:100 题数:30 一、单选题(共20题,共80分) 1. 2025年初,中国科技初创公司深度求索在大模型领域迅速崛起,其开源的大模型成为全球AI领域的焦…

spark local模式搭建运行示例

Apache Spark 是一个强大的分布式计算框架,但在本地模式下,它也可以作为一个单机程序运行,非常适合开发和测试阶段。以下是一个简单的示例,展示如何在本地模式下搭建和运行 Spark 程序。 一、环境准备 安装 Java Spark 需要 Java…

【人工智能】解锁 AI 潜能:DeepSeek 大模型迁移学习与特定领域微调的实践

《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 随着大型语言模型(LLMs)的快速发展,迁移学习与特定领域微调成为提升模型性能的关键技术。本文深入探讨了 DeepSeek 大模型在迁移学习中的…

视频智能分析平台EasyCVR无线监控:全流程安装指南与功能应用解析

在当今数字化安防时代,无线监控系统的安装与调试对于保障各类场所的安全至关重要。本文将结合EasyCVR视频监控的强大功能,为您详细阐述监控系统安装过程中的关键步骤和注意事项,帮助您打造一个高效、可靠的监控解决方案。 一、调试物资准备与…

【k8s系列7-更新中】kubeadm搭建Kubernetes高可用集群-三主两从

主机准备 结合前面的章节,这里需要5台机器,可以先创建一台虚拟机作为基础虚拟机。优先把5台机器的公共部分优先在一台机器上配置好 1、配置好静态IP地址 2、主机名宇IP地址解析 [root@localhost ~]# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost…

【Java后端】MyBatis 与 MyBatis-Plus 如何防止 SQL 注入?从原理到实战

在日常开发中,SQL 注入是一种常见但危害巨大的安全漏洞。如果你正在使用 MyBatis 或 MyBatis-Plus 进行数据库操作,这篇文章将带你系统了解:这两个框架是如何防止 SQL 注入的,我们又该如何写出安全的代码。 什么是 SQL 注入&#…

数据分析案例:医疗健康数据分析

目录 数据分析案例:医疗健康数据分析1. 项目背景2. 数据加载与预处理2.1 加载数据2.2 数据清洗3. 探索性数据分析(EDA)3.1 再入院率概览3.2 按年龄分组的再入院率3.3 住院时长与再入院4. 特征工程与可视化5. 模型构建与评估5.1 数据划分5.2 训练逻辑回归5.3 模型评估6. 业务…

3台CentOS虚拟机部署 StarRocks 1 FE+ 3 BE集群

背景:公司最近业务数据量上去了,需要做一个漏斗分析功能,实时性要求较高,mysql已经已经不在适用,做了个大数据技术栈选型调研后,决定使用StarRocks StarRocks官网:StarRocks | A High-Performa…

软件设计师/系统架构师---计算机网络

概要 什么是计算机网络? 计算机网络是指将多台计算机和其他设备通过通信线路互联,以便共享资源和信息的系统。计算机网络可以有不同的规模,从家庭网络到全球互联网。它们可以通过有线(如以太网)或无线(如W…

1.5软考系统架构设计师:架构师的角色与能力要求 - 超简记忆要点、知识体系全解、考点深度解析、真题训练附答案及解析

超简记忆要点 角色职责 需求规划→架构设计→质量保障 能力要求 技术(架构模式/性能优化) 业务(模型抽象→技术方案) 管理(团队协作/风险控制) 知识体系 基础:CAP/设计模式/网络协议案例&am…

基于STM32的汽车主门电动窗开关系统设计方案

芯片和功能模块选型 主控芯片 STM32F103C8T6:基于 ARM Cortex - M3 内核,有丰富的 GPIO 接口用于连接各类外设,具备 ADC 模块可用于电流检测,还有 CAN 控制器方便实现 CAN 总线通信。它资源丰富、成本低,适合学生进行 DIY 项目开发。按键模块 轻触按键:用于控制车窗的自…

第十三届蓝桥杯 2022 C/C++组 修剪灌木

目录 题目: 题目描述: 题目链接: 思路: 核心思路: 思路详解: 代码: 代码详解: 题目: 题目描述: 题目链接: P8781 [蓝桥杯 2022 省 B] 修…