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

设计模式教程:中介者模式(Mediator Pattern)

中介者模式是一种行为型设计模式,它用于减少对象之间的直接依赖关系。通过引入一个中介者对象,所有对象的交互都通过中介者进行,而不是直接相互通信。这种模式的主要目的是减少对象之间的耦合,提升系统的灵活性和可维护性。

1. 定义和意图

意图: 中介者模式通过一个中介者对象来协调和控制多个对象之间的交互,从而减少多个对象之间的直接联系,降低系统的复杂度。对象通过中介者进行通信,而不直接依赖于彼此。

2. 组成部分

中介者模式通常由以下几个角色组成:

  • Mediator(中介者接口):声明了一个方法,用于同事对象之间的通信。
  • ConcreteMediator(具体中介者):实现中介者接口,负责协调同事对象之间的交互。
  • Colleague(同事类):定义同事对象,所有对象与中介者的交互都通过中介者进行。
  • ConcreteColleague(具体同事类):继承自同事类,能够通过中介者与其他对象进行交互。

3. 结构图

                +---------------------+|    Mediator         |+---------------------+| + notify()          |+---------------------+^|+---------------------------+| ConcreteMediator           |+---------------------------+| + colleague1: Colleague1   || + colleague2: Colleague2   |+---------------------------+|+--------------------------+------------------+|                                              |
+---------------+                             +------------------+
| Colleague1    |                             | Colleague2       |
+---------------+                             +------------------+
| + setMediator()|                             | + setMediator()  |
| + action()     |                             | + action()       |
+---------------+                             +------------------+

4. 代码实现

4.1 中介者接口

首先,定义中介者接口,声明同事对象交互的方法。

// 中介者接口
public interface Mediator {void notify(Colleague colleague, String message);
}
4.2 具体中介者

然后,定义一个具体的中介者类,负责协调各个同事对象之间的交互。

// 具体中介者
public class ConcreteMediator implements Mediator {private Colleague1 colleague1;private Colleague2 colleague2;// 设置同事对象public void setColleague1(Colleague1 colleague1) {this.colleague1 = colleague1;}public void setColleague2(Colleague2 colleague2) {this.colleague2 = colleague2;}@Overridepublic void notify(Colleague colleague, String message) {if (colleague == colleague1) {// 如果是colleague1,通知colleague2colleague2.receive(message);} else {// 如果是colleague2,通知colleague1colleague1.receive(message);}}
}
4.3 同事类

接下来,定义一个同事类的接口,所有同事类都必须实现这个接口。

// 同事类接口
public abstract class Colleague {protected Mediator mediator;public Colleague(Mediator mediator) {this.mediator = mediator;}// 设置中介者public void setMediator(Mediator mediator) {this.mediator = mediator;}// 接收消息public abstract void receive(String message);// 发送消息public abstract void send(String message);
}
4.4 具体同事类

然后,定义具体的同事类,负责执行具体的操作。

// 具体同事类1
public class Colleague1 extends Colleague {public Colleague1(Mediator mediator) {super(mediator);}@Overridepublic void receive(String message) {System.out.println("Colleague1 received: " + message);}@Overridepublic void send(String message) {System.out.println("Colleague1 sends: " + message);mediator.notify(this, message);}
}// 具体同事类2
public class Colleague2 extends Colleague {public Colleague2(Mediator mediator) {super(mediator);}@Overridepublic void receive(String message) {System.out.println("Colleague2 received: " + message);}@Overridepublic void send(String message) {System.out.println("Colleague2 sends: " + message);mediator.notify(this, message);}
}
4.5 使用示例

最后,创建一个应用程序来使用中介者模式。

public class Main {public static void main(String[] args) {// 创建中介者对象ConcreteMediator mediator = new ConcreteMediator();// 创建具体同事对象Colleague1 colleague1 = new Colleague1(mediator);Colleague2 colleague2 = new Colleague2(mediator);// 设置同事对象mediator.setColleague1(colleague1);mediator.setColleague2(colleague2);// 发送消息colleague1.send("Hello from Colleague1!");colleague2.send("Hello from Colleague2!");}
}

4.6 输出结果

Colleague1 sends: Hello from Colleague1!
Colleague2 received: Hello from Colleague1
Colleague2 sends: Hello from Colleague2!
Colleague1 received: Hello from Colleague2

5. 优点

  • 减少类之间的依赖:通过中介者模式,同事类不再直接引用彼此,而是通过中介者对象进行通信,从而减少了类之间的耦合。
  • 集中化通信逻辑:中介者将交互的逻辑集中在一个地方,便于维护和扩展。
  • 扩展性强:如果添加新的同事类,只需要在中介者中进行适配,而不需要修改现有的类。

6. 缺点

  • 中介者的复杂性:当系统中存在大量同事对象时,中介者对象的职责会变得非常复杂,可能会导致中介者本身的代码膨胀。
  • 过度集中:如果所有的交互都通过中介者,可能会导致中介者对象成为“上帝对象”,承担过多的职责,变得难以维护。

7. 应用场景

中介者模式适用于以下情况:

  • 复杂的对象交互:当多个对象之间有复杂的交互关系时,使用中介者模式能够简化这些交互,避免直接依赖。
  • 解耦合:如果对象之间需要进行频繁的交互,但又不希望它们之间过于紧密地耦合,可以通过中介者来解耦。
  • 多个对象的通信协调:适用于需要协调多个对象行为的场景,比如 UI 界面中多个控件之间的交互。

8. 总结

中介者模式通过将对象间的交互集中到一个中介者对象中,降低了对象之间的耦合度,简化了对象间的通信逻辑。它使得系统更容易维护和扩展,但也可能导致中介者过于复杂,成为系统的瓶颈。因此,在使用中介者模式时,需要权衡其优缺点,根据具体的需求来选择是否使用。

版权声明
  1. 本文内容属于原创,欢迎转载,但请务必注明出处和作者,尊重原创版权。
  2. 转载时,请附带原文链接并注明“本文作者:扣丁梦想家
  3. 禁止未经授权的商业转载。

如果您有任何问题或建议,欢迎留言讨论。

相关文章:

设计模式教程:中介者模式(Mediator Pattern)

中介者模式是一种行为型设计模式,它用于减少对象之间的直接依赖关系。通过引入一个中介者对象,所有对象的交互都通过中介者进行,而不是直接相互通信。这种模式的主要目的是减少对象之间的耦合,提升系统的灵活性和可维护性。 1. 定…...

编写dockercompose脚本,管理redis,activemq,mysql5.7

编写dockercompose脚本,管理redis,activemq,mysql5.7,mysql的root密码设置Duke2007,redis密码设置duke0591 Docker Compose 多服务编排脚本(安全增强版) yaml 复制 services: # # MySQL 5.7 服务配置 #…...

【编程语言】委托与函数指针

委托与函数指针的相似之处: 指向方法:C# 的委托和 C 的函数指针都可以用来指向一个方法或函数。调用方法:它们都可以通过引用(委托或函数指针)来调用指向的方法。 委托与函数指针的主要区别: 类型安全&am…...

基于vue和微信小程序的校园自助打印系统(springboot论文源码调试讲解)

第3章 系统设计 3.1系统功能结构设计 本系统的结构分为管理员和用户、店长。本系统的功能结构图如下图3.1所示: 图3.1系统功能结构图 3.2数据库设计 本系统为小程序类的预约平台,所以对信息的安全和稳定要求非常高。为了解决本问题,采用前端…...

数字后端实现之Innovus中open net原因解析及解决方案

数字IC后端设计实现Innovus中我们经常会碰到如下的WARNING警告信息。这个log是在route或ECO Route阶段报的。这个WARNING必须要看,因为这里是报告当前设计存在open的net,即某些pin只有逻辑连接,而没有实际的物理连接。 这里正常工具应该报ERR…...

MATLAB基础学习相关知识

MATLAB安装参考:抖音-记录美好生活 MATLAB基础知识学习参考:【1小时Matlab速成教程-哔哩哔哩】 https://b23.tv/CnvHtO3 第1部分:变量定义和基本运算 生成矩阵: % 生成矩阵% 直接法% ,表示行 ;表示列 a [1,2,3;4,5,6;7,8,9];%…...

Mac系统下使用Docker快速部署MaxKB:打造本地知识库问答系统

随着大语言模型的广泛应用,知识库问答系统逐渐成为提升工作效率和个人学习的有力工具。MaxKB是一款基于LLM(Large Language Model)大语言模型的知识库问答系统,支持多模型对接、文档上传和自动爬取等功能。本文将详细介绍如何在Ma…...

RT-Thread+STM32L475VET6——icm20608传感器

文章目录 前言一、板载资源二、具体步骤1.打开CubeMX进行配置1.1 使用外部高速时钟,并修改时钟树1.2 打开I2C3,参数默认即可(I2C根据自己需求调整)1.3 打开串口1.4 生成工程 2. 添加icm20608软件包3. 使能传感器,打开动态链接库4.…...

【信息系统项目管理师-案例真题】2022下半年案例分析答案和详解

更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 试题一(24分)【问题1】(6分)【问题2】(10分)【问题3】(8分)试题二(26分)【问题1】(8分)【问题2】(8分)【问题3】(4分)【问题4】(6分)试题三(25分)【问题1】(12分)【问题2】(7分)【问题…...

3D机器视觉工业3D图像格式常见的格式

工业3D图像格式主要用于存储和交换三维模型数据,常见的格式包括: STL (Stereolithography) 用途: 3D打印和快速成型。 特点: 存储三角面片信息,文件较小,但不包含颜色和材质数据。STEP (Standard for the Exchange of Product Data) 用途: CAD数据交换。 特点: 支持几何、拓…...

SkyWalking集成Kafka实现日志异步采集经验总结

SkyWalking日志异步采集架构 【重点知识】 1、【Agent】kafka-reporter-plugin-x.x.x.jar包放plugins目录后必走kafka(kafka没有正确配置就会报错) 2、【Agent】异步如不开启数据压缩,日志数据较大,pod多、业务大时容易造成网络…...

Java知识点——IO流

目录 一、IO流基础概念 二、常见的IO流类 三、字符流 1.字符输入流(Reader)与字符输出流(Writer) 2.常用实现类 3.实例 四、字节流 1.字节输入流(InputStream)与字节输出流(OutputStrea…...

uniapp h5端和app端 使用 turn.js

前提:添加页后,添加页与当前页会重叠在一起,不知道为什么,没有找到解决办法 1.h5端 <template><view class"container"><view id"flipbook"><view class"page page1">Page 1</view><view class"page pag…...

使用大语言模型(Deepseek)构建一个基于 SQL 数据的问答系统

GitHub代码仓库 架构 从高层次来看&#xff0c;这些系统的步骤如下&#xff1a; 将问题转换为SQL查询&#xff1a;模型将用户输入转换为SQL查询。 执行SQL查询&#xff1a;执行查询。 回答问题&#xff1a;模型根据查询结果响应用户输入。 样本数据 下载样本数据&#xf…...

时间转换(acwing)c/c++/java/python

读取一个整数值&#xff0c;它是工厂中某个事件的持续时间&#xff08;以秒为单位&#xff09;&#xff0c;请你将其转换为小时&#xff1a;分钟&#xff1a;秒来表示。 输入格式 输入一个整数 NN。 输出格式 输出转换后的时间表示&#xff0c;格式为 hours:minutes:second…...

连接Sql Server时报错无法通过使用安全套接字层加密与 SQL Server 建立安全连接

文章目录 一. 前言二. 解决方案 方案1方案2 三. 总结 一. 前言 在《数据库原理》这门课的实验上&#xff0c;需要使用SQL Server&#xff0c;然后使用jdbc连接sql server突然报错为&#xff1a;SQLServerException: “Encrypt”属性设置为“true”且 “trustServerCertific…...

基于CNN的FashionMNIST数据集识别3——模型验证

源码 import torch import torch.utils.data as Data from torchvision import transforms from torchvision.datasets import FashionMNIST from model import LeNetdef test_data_process():test_data FashionMNIST(root./data,trainFalse,transformtransforms.Compose([tr…...

go channel 的用法和核心原理、使用场景

一、Channel 的核心用法 1. 基本操作 // 创建无缓冲 Channel&#xff08;同步通信&#xff09; ch : make(chan int) // 创建有缓冲 Channel&#xff08;容量为5&#xff0c;异步通信&#xff09; bufferedCh : make(chan int, 5) // 发送数据到 Channel ch <- 42 // 从…...

pyside6学习专栏(七):自定义QTableWidget的扩展子类QTableWidgetEx

PySide6界面编程中较常用的控件还有QTableWidget表格控件&#xff0c;用来将加载的数据在表格中显示出来&#xff0c;下面继承QTableWidget编写其扩展子类QTableWidgetEx,来实现用单元格来显示除数据文字外&#xff0c;还可以对表格的单元格的文字颜色、背景底色进行设置&#…...

Mybatis常用动态 SQL 相关标签

1. <if> 用于条件判断&#xff0c;当满足条件时执行对应的 SQL 片段。 示例: <select id"findUser" resultType"User">SELECT * FROM usersWHERE 11<if test"name ! null and name ! ">AND name #{name}</if><if…...

【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15

缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下&#xff1a; struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

Flask RESTful 示例

目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题&#xff1a; 下面创建一个简单的Flask RESTful API示例。首先&#xff0c;我们需要创建环境&#xff0c;安装必要的依赖&#xff0c;然后…...

遍历 Map 类型集合的方法汇总

1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时&#xff0c;可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案&#xff1a; 1. 检查电源供电问题 问题原因&#xff1a;多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

Java 加密常用的各种算法及其选择

在数字化时代&#xff0c;数据安全至关重要&#xff0c;Java 作为广泛应用的编程语言&#xff0c;提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景&#xff0c;有助于开发者在不同的业务需求中做出正确的选择。​ 一、对称加密算法…...