Java中的中介者模式:解耦复杂系统的有效策略
Java中的中介者模式:解耦复杂系统的有效策略
在软件开发中,随着系统规模的扩大和复杂度的增加,各组件之间的直接交互会导致代码的耦合性增高,从而影响系统的可维护性和可扩展性。为了应对这种复杂性,中介者模式(Mediator Pattern)作为一种设计模式,提供了一种有效的解耦策略。本文将详细介绍Java中的中介者模式,包括其基本概念、优缺点、实现方法以及实际应用,并通过示例代码展示如何在Java中应用这一模式来构建更灵活、更易于维护的系统。
1. 中介者模式的概念
1.1 什么是中介者模式?
中介者模式是一种行为型设计模式,用于定义一个对象(即中介者)来封装对象之间的交互。这种模式通过将对象间的直接通信转移到中介者对象,从而减少对象之间的直接依赖和复杂性。在中介者模式中,各对象通过中介者与其他对象进行交互,而不是直接相互调用,这使得各个对象可以更专注于自身的逻辑,而不需要关心与其他对象的交互细节。
1.2 中介者模式的核心思想
中介者模式的核心思想是将对象间复杂的交互关系集中到一个中介者对象中,从而减少对象间的耦合。这样,系统中的对象不再直接引用彼此,而是通过中介者进行通信。这种方式的主要优点是降低了系统的耦合度,使得对象之间的关系变得更加简单和可控。
1.3 中介者模式的适用场景
中介者模式适用于以下场景:
-
复杂对象之间的通信:当多个对象之间存在复杂的交互关系,且每个对象都需要知道其他对象的状态时,中介者模式可以有效减少对象间的直接依赖。
-
系统可扩展性要求高:当系统需要频繁地添加或修改对象时,通过中介者模式可以降低对其他对象的影响,从而提高系统的可扩展性。
-
解耦需求:当需要将系统中各对象的交互解耦,使得各对象独立开发、测试和维护时,中介者模式是一个有效的解决方案。
2. 中介者模式的结构与参与者
2.1 模式结构
中介者模式通常包含以下几个核心角色:
-
Mediator(中介者接口):定义了各个同事对象之间通信的接口。通常,这个接口会有一个方法,用于发送消息或进行某种操作。
-
ConcreteMediator(具体中介者):实现了中介者接口,负责协调同事对象之间的通信和交互。它通常维护了对各个同事对象的引用。
-
Colleague(同事类):各个同事类实现或继承同事接口,并通过中介者来进行通信。这些类通常只关心自身的功能和逻辑,不直接与其他同事对象进行交互。
2.2 参与者之间的关系
在中介者模式中,同事对象不直接通信,而是通过中介者来协调。中介者会接收来自同事对象的消息,并根据需求将消息传递给其他相关的同事对象。通过这种方式,中介者对象起到了“调度中心”的作用,将复杂的对象间通信集中管理,从而简化了系统中的对象关系。
3. 中介者模式的实现
在Java中实现中介者模式通常涉及定义一个中介者接口,创建具体的中介者类,并让各个同事类通过中介者进行通信。下面我们通过一个简单的聊天系统示例,展示如何在Java中实现中介者模式。
3.1 定义中介者接口
首先,我们定义一个中介者接口ChatMediator
,它包含一个用于发送消息的方法。
public interface ChatMediator {void sendMessage(String message, User user);void addUser(User user);
}
3.2 实现具体中介者类
接下来,我们创建一个具体的中介者类ChatMediatorImpl
,它负责管理用户列表并协调消息的发送。
import java.util.ArrayList;
import java.util.List;public class ChatMediatorImpl implements ChatMediator {private List<User> users;public ChatMediatorImpl() {this.users = new ArrayList<>();}@Overridepublic void sendMessage(String message, User user) {for (User u : this.users) {// 消息不会发回给发送消息的用户if (u != user) {u.receive(message);}}}@Overridepublic void addUser(User user) {this.users.add(user);}
}
3.3 定义同事类
接下来,我们定义一个抽象的同事类User
,以及两个具体的用户类UserImpl
。
public abstract class User {protected ChatMediator mediator;protected String name;public User(ChatMediator mediator, String name) {this.mediator = mediator;this.name = name;}public abstract void send(String message);public abstract void receive(String message);
}public class UserImpl extends User {public UserImpl(ChatMediator mediator, String name) {super(mediator, name);}@Overridepublic void send(String message) {System.out.println(this.name + " 发送消息: " + message);mediator.sendMessage(message, this);}@Overridepublic void receive(String message) {System.out.println(this.name + " 收到消息: " + message);}
}
3.4 客户端代码
最后,我们编写客户端代码来测试中介者模式的实现。
public class MediatorPatternTest {public static void main(String[] args) {ChatMediator mediator = new ChatMediatorImpl();User user1 = new UserImpl(mediator, "Alice");User user2 = new UserImpl(mediator, "Bob");User user3 = new UserImpl(mediator, "Charlie");User user4 = new UserImpl(mediator, "David");mediator.addUser(user1);mediator.addUser(user2);mediator.addUser(user3);mediator.addUser(user4);user1.send("Hello everyone!");}
}
3.5 运行结果
当运行上述代码时,输出结果将如下所示:
Alice 发送消息: Hello everyone!
Bob 收到消息: Hello everyone!
Charlie 收到消息: Hello everyone!
David 收到消息: Hello everyone!
通过中介者模式,User
对象之间的消息传递不再需要直接引用彼此,而是通过中介者ChatMediatorImpl
来协调。这降低了对象之间的耦合度,使得系统更易于扩展和维护。
4. 中介者模式的优缺点
4.1 优点
-
降低耦合:中介者模式通过引入中介者对象,将对象之间的通信集中管理,从而减少了对象之间的直接依赖。这种解耦使得系统更容易扩展和维护。
-
简化对象间的通信:对象之间不再需要直接引用和调用彼此的接口,而是通过中介者进行间接通信,这使得系统中的对象关系更为简单。
-
集中控制:通过中介者模式,系统中的复杂交互逻辑可以集中在中介者对象中,从而提高了控制和管理的集中性。
4.2 缺点
-
中介者的复杂性增加:随着系统的复杂度增加,中介者对象本身可能变得非常复杂,承担了大量的协调工作。这可能导致中介者对象变成一个“上帝对象”(God Object),违背单一职责原则。
-
潜在的性能问题:在某些高性能要求的场景下,通过中介者进行间接通信可能会引入额外的延迟,从而影响系统性能。
5. 中介者模式的实际应用
5.1 GUI组件管理
在图形用户界面(GUI)开发中,中介者模式常用于管理各个GUI组件之间的交互。例如,在一个对话框中,按钮、文本框、复选框等组件可以通过一个中介者对象进行协调,而不需要彼此直接通信。这使得界面组件的管理更加简单和可扩展。
5.2 聊天系统
如前文示例所示,中介者模式可以用于构建聊天系统。在聊天系统中,用户之间的消息传递可以通过一个中介者对象(如聊天室服务器)来进行协调,从而避免用户对象之间的直接耦合。
5.3 工作流管理
在工作流管理系统中,中介者模式可以用于协调各个工作节点之间的通信。每个工作节点可以通过中介者来传递消息或任务,从而实现工作流的自动化和协调
。
6. 中介者模式的扩展与优化
6.1 引入观察者模式
在某些情况下,中介者模式可以与观察者模式结合使用。通过将中介者对象设为观察者,系统中的对象可以通过事件机制通知中介者,从而简化中介者的实现和对象之间的通信。
6.2 动态中介者
对于某些动态场景,可以引入动态中介者的概念,使得中介者可以根据运行时的需求动态生成和管理对象之间的交互。这种方式适用于需要频繁变更或扩展的系统。
7. 结论
中介者模式是一种有效的解耦策略,特别适用于复杂系统中对象之间的交互管理。通过引入中介者对象,系统中的对象可以避免直接耦合,从而提高系统的可维护性和可扩展性。尽管中介者模式在某些情况下可能引入复杂性和性能问题,但在大多数情况下,它为解决系统复杂性提供了一种优雅而实用的方案。
在Java开发中,中介者模式可以广泛应用于GUI组件管理、聊天系统、工作流管理等场景。通过合理设计和优化,中介者模式可以帮助开发者构建更加灵活和易于维护的系统。
相关文章:

Java中的中介者模式:解耦复杂系统的有效策略
Java中的中介者模式:解耦复杂系统的有效策略 在软件开发中,随着系统规模的扩大和复杂度的增加,各组件之间的直接交互会导致代码的耦合性增高,从而影响系统的可维护性和可扩展性。为了应对这种复杂性,中介者模式&#…...

transformer(李宏毅老师系列)
自学参考: Transformer:Attention Is All You Need Transformer论文逐段精读 视频课 课件资料 笔记 一、引入 seq2seq:输入一个序列的向量作为input,output的长度由机器自己决定seq2seq model应用: 语音辨识 输入是声音讯号的一串vector 输出…...

XCode15.4真机运行调试
更新Xcode后,没有模拟器内容,而且真机也不显示,编译按钮无法点击,设备在管理运行目标中可见,但无法选中解决方案:下载iOS17.5模拟器,但最坑的是直接点击“Get”下载总是中断,且无法断…...

Google Mock 和 Google Test编写单元测试入门(环境配置、简单执行)
文章目录 环境的配置方法1:从源代码构建第一步:克隆库的源代码第二步:构建库 方法 2:使用 CMake 的 FetchContent示例 CMakeLists.txt 项目的创建项目结构CMakeLists.txt (根目录)main.cpp (示例程序)tests/CMakeLists.txt (测试部…...

shell外壳与Linux权限
🌈个人主页:Yui_ 🌈Linux专栏:Linux 🌈C语言笔记专栏:C语言笔记 🌈数据结构专栏:数据结构 文章目录 1.shell命令以及运行原理2. Linux权限的概念3.Linux权限管理3.1 文件访问者的分类…...

越混越好的项目经理做对了哪些事?现在知道还不晚
作为一名项目经理,你最害怕的是什么? 是做不完的项目?延迟的进度条?还是团队人心涣散? 很多人都知道,得人心者得天下,一个成功的领导者,一定是能做到让人心服口服的。如果失去了团…...

haproxy是什么?以及haproxy基础实验
目录 一、什么是负载均衡? 二、为什么要用haproxy? 三、haproxy的基本部署实验: 3.1 基本配置实验 环境准备: 详细步骤: 3.2 haproxy-多进程与多线程实验: 多进程: 多线程:…...

【向量数据库】向量数据库的构建和检索
1、使用 sentence-transformers 将文本编码为向量 安装 sentence-transformers: pip install -U sentence-transformers在 huggingface 下载 all-MiniLM-L6-v2 模型权重(1_Pooling 是文件夹,里面包含一个 config.json 文件)&…...

Mysql基础篇之DQL语言
Mysql基础篇之DQL语言 1. 基础查询特点语法格式闲言碎语 2. 条件查询语法格式条件表达式逻辑表达式模糊查询 3. 排序查询4. 常见函数单行函数1. 字符函数2. 数学函数3. 日期函数4. 流程控制函数5. 其他函数 分组函数 5. 分组查询分组函数语法格式特点 6. 多表连接查询分类SQL 七…...

python async
要使用 Python 的 async 特性编写一个代码,以交替使用两个 AI API 处理数据,您可以按照以下步骤进行。假设这两个 AI API 的调用是异步的,并且我们需要在两个 API 之间轮流处理一组数据。 import asyncio import aiohttp async def call_ap…...

利用QT和FFmpeg实现一个简单的视频播放器
在当今的多媒体世界中,视频播放已成为不可或缺的一部分。从简单的媒体播放器到复杂的视频编辑软件,视频解码和显示技术无处不在。本示例使用Qt和FFmpeg构建一个简单的视频播放器。利用ffmpeg解码视频,通过QWidget渲染解码后的图像,…...

怎么用云手机进行TikTok矩阵运营
TikTok作为炙手可热的社交媒体巨头,已经吸引了亿万用户的目光。随着科技的飞速发展,云手机的出现为TikTok矩阵运营注入了新的活力。本文将深入探讨云手机在TikTok矩阵运营中的实际应用,并分享一系列高效策略与技巧。 (1࿰…...

TCP/IP 协议及其协议号
协议号十六进制协议号协议介绍10x1ICMP (Internet Control Message Protocol)20x2IGMP (Internet Group Management Protocol) 30x3GGP (Gateway-to-Gateway Protocol) 40x4IPv4 (encapsulation) 50x5ST (Stream Protocol) 60x6TCP (Transm…...

【传知代码】机器情绪及抑郁症算法 四(论文复现)
在现代心理健康研究中,抑郁症一直是一个备受关注的课题。随着科学的进步,研究人员逐渐认识到,抑郁症的成因远不止单一因素,而是由复杂的生物学、心理学和社会环境因素交织而成的。最近,MSA(综合性综合性模型…...

C#开启和关闭UAC功能
在开发软件或制作安装包时,有时会需要管理员权限 ,但是又不想弹出UAC对话框。 可以编写一个小工具,检测UAC是否关闭。如果没有关闭,就自动关闭UAC。 实现比较简单, 找到注册表 计算机\HKEY_LOCAL_MACHINE\SOFTWARE…...

LVS的简单配置及对Mysql主从复制的补充
Day 22 LVS的配置 环境准备 DSN() 用来解析各主机的域名和ip地址,配置域名解析huajuan,负责管理其他主机 web1--->web1.tangpin.huajuan web2--->web2.tangpin.huajuan dns--->dns.tangpin.huajuan web1(192.168.2.200) 用nginx…...

七夕情人节特辑:程序员的浪漫惊喜,9个表白源码,甜蜜编程陪你过节
大家好呀👋,今天是中国的七夕情人节,一个充满浪漫与爱的日子。为了庆祝这个特别的节日,我为大家精心准备了9个表白专用的前端小项目。这些项目涵盖了“我爱你”网站、爱情表白网站和心形动画等,通过HTML、CSS和一点点J…...

Mask-Rcnn
一 、FPN层 FPN层的基本作用 基本网络架构 基本思想 将多个阶段特征图融合在一起,这就相当于既有了高层的语义特征,也有了低层的轮廓特征 二、RPN层 三、ROI Align层...

Python图像背景去除
目录 🎁库的导入 🎀库的安装 🎁rembg库去除背景 🎁效果 🎁文末彩蛋 今天来介绍一个特别有趣的python库,rembg库,全称是“Remove Background”的缩写,意为“去除背景”ÿ…...

【C语言篇】C语言常考及易错题整理DAY1
文章目录 C语言常考及易错题整理选择题全局、局部和静态变量#define与typedef转义字符操作符循环其他 编程题计算日期到天数转换柯尼希定理旋转数组的最小数字描述错误的集合整数转换密码检查 C语言常考及易错题整理 选择题 全局、局部和静态变量 执行下面程序,正…...

MySQL5.7之源码安装
文章目录 下载编译&打包初始化数据目录启动服务器更改/设置root密码 下载 下载地址:https://downloads.mysql.com/archives/community/ 推荐下载 All Operating Systems (Generic) (Architecture Independent), Compressed TAR ArchiveIncludes Boost Headers …...

【Linux学习 | 第3篇】Linux系统安装 jdk+Tomcat+MySQL+lrzsz
文章目录 Linux—day31. 软件安装方式2. 安装jdk3. 安装Tomcat3.1 安装步骤:3.2 防火墙操作3.3 停止Tomcat服务的方式 4. 安装MySQL5. 安装lrzsz5.1 操作步骤 Linux—day3 Linux系统中软件安装 1. 软件安装方式 二进制发布包安装:软件已经针对具体平台…...

python语言day5 MD5 json
md5: python提供了内置的md5加密功能,使用md5模拟一个小项目: 注册: 启动py程序,在控制台界面提示用户输入用户名及密码; 使用md5加密 密码; 创建txt文件记录输入的用户名 和密文。 登录&…...

【Python学习手册(第四版)】学习笔记19-函数的高级话题
个人总结难免疏漏,请多包涵。更多内容请查看原文。本文以及学习笔记系列仅用于个人学习、研究交流。 本文主要介绍函数相关的高级概念:递归函数、函数注解、lambda表达式函数,常用函数工具如map、filter、reduce,以及通用的函数设…...

Selenium + Python 自动化测试11(unittest组织用例)
我们的目标是:按照这一套资料学习下来,大家可以独立完成自动化测试的任务。 上一篇我们讨论了unittest基本使用方法。 本篇文章我们接着讲。一些概念和一些常用的构造测试集的方法。 1、基本概念 1)Test Case 一个Test Case的实例就是一个测…...

【唐氏题目 nt题】与众不同
# 与众不同 ## 题目描述 A是某公司的CEO,每个月都会有员工把公司的盈利数据送给A,A是个与众不同的怪人,A不注重盈利还是亏本,而是喜欢研究「完美序列」:一段连续的序列满足序列中的数互不相同。 A想知道区间[L,R]之…...

2000块的活嫌低?这个 6 位数的项目,你可不能错过哟!
2000块钱嫌低?这个6位数的项目,你可不能错过,关注有好礼。 最近写了一篇“接了一个2000块钱的活,大家看看值不值”的文章,发现流量和大家互动的热情出奇的高,可能是跟有钱有关的缘故,大家不是奔…...

【Postman工具】
一.接口扫盲 1.什么是接口? 接口是系统之间数据交互的通道。拿小红到沙县点餐为例:小红想吃鸭腿饭。她要用什么语言来表达?跟谁表达?通过什么表达?按照生活习惯应该是:小红根据菜单对服务员用中文表达她想要…...

全网超详细攻略-从入门到精通haproxy七层代理
目录 一.haproxy概述 1.1 haproxy简介 1.2 haproxy的主要特性 1.3 haproxy的优缺点 二.负载均衡介绍 2.1 什么是负载均衡 2.2 为什么用负载均衡 2.3 负载均衡类型 2.3.1 四层负载均衡 2.3.2 七层负载均衡 2.3.3 四层和七层的区别 三.haproxy的安装及服务 3.1 实验环…...

AI编程辅助工具:CodeGeeX 插件使用
CodeGeeX 插件使用 前言1.支持的平台2.安装步骤3.启用插件4.代码生成5.代码优化 前言 CodeGeeX 是一款基于 AI 技术的编程助手插件,旨在帮助开发者提高编程效率和代码质量。它能够智能生成代码、优化现有代码、自动生成文档以及回答编程相关的问题。无论您是初学者…...