23种设计模式之中介者模式
目录
- 1. 简介
- 2. 代码
- 2.1 Mediator (中介者接口)
- 2.2 ChatRoom (具体中介者类)
- 2.3 User (同事接口)
- 2.4 ChatUser (具体同事类)
- 2.5 Test (测试)
- 2.6 运行结果
- 3. 使用场景
- 4. 优缺点
- 5. 总结
1. 简介
中介者模式(Mediator Pattern) 是一种行为设计模式,它通过定义一个中介对象来封装一系列对象之间的交互。中介者使各对象之间不需要显式地相互引用,从而使它们之间的耦合松散,并且可以独立地改变它们之间的交互。
例如,在一个聊天软件系统中,多个用户(同事、朋友等)之间的聊天消息传递可以通过一个服务器(中介者)来进行。用户不需要直接知道其他用户的联系方式或者网络地址等信息,只需要将消息发送给服务器,服务器再将消息转发给指定的其他用户。
结构:
- 中介者(Mediator)接口
这是所有具体中介者类都要实现的接口,它定义了用于协调各同事对象(Colleague)之间交互的方法。 - 具体中介者(Concrete Mediator)类
具体中介者类实现了中介者接口,它包含了对多个同事对象的引用,并通过这些引用协调同事对象之间的交互。在聊天软件中,服务器类就是具体中介者类,它维护了在线用户列表,并负责将消息从一个用户转发给另一个用户。 - 同事(Colleague)接口
同事接口定义了同事对象与中介者进行交互的方法。在聊天软件中,这个接口可以包含发送消息和接收消息的方法。 - 具体同事(Concrete Colleague)类
具体同事类实现了同事接口,它持有一个中介者对象的引用,通过这个引用与其他同事进行间接的交互。在聊天软件中,用户客户端类就是具体同事类,它在发送消息时将消息发送给服务器(中介者),接收消息时也是从服务器获取消息。
2. 代码
2.1 Mediator (中介者接口)
public interface Mediator {void work(User user, String message);
}
2.2 ChatRoom (具体中介者类)
import java.util.ArrayList;
import java.util.List;public class ChatRoom implements Mediator{private List<User> users = new ArrayList<>();@Overridepublic void work(User user, String message) {for (User otherUser : users) {if (otherUser!= user) {otherUser.receiveMessage(message);}}}public void addUser(User user) {users.add(user);}
}
2.3 User (同事接口)
public interface User {void sendMessage(String message);void receiveMessage(String message);
}
2.4 ChatUser (具体同事类)
public class ChatUser implements User{private Mediator mediator;private String name;public ChatUser(Mediator mediator, String name) {this.mediator = mediator;this.name = name;}@Overridepublic void sendMessage(String message) {mediator.work(this,message);}@Overridepublic void receiveMessage(String message) {System.out.println(name + " received message: " + message);}
}
2.5 Test (测试)
public class Test {public static void main(String[] args) {ChatRoom mediator = new ChatRoom();User robert = new ChatUser(mediator,"Robert");User john = new ChatUser(mediator,"John");mediator.addUser(robert);mediator.addUser(john);robert.sendMessage("Hi John!");john.sendMessage("Hello Robert!");}
}
2.6 运行结果
John received message: Hi John!
Robert received message: Hello Robert!
3. 使用场景
- 复杂交互关系:当系统中存在多个对象之间复杂的依赖关系时,中介者模式可以简化这些关系,使系统更加清晰易维护。例如,在一个聊天室应用中,用户通过中介者(如聊天室)进行消息传递,而不是直接与其他用户建立连接,这样可以降低直接依赖,增加系统的灵活性。
- 减少子类生成:在需要处理大量子类的情况下,中介者模式可以集中处理对象间的交互逻辑,避免直接耦合,从而减少子类的数量。
- 强耦合问题:中介者模式能够降低对象间的强耦合,提高系统的灵活性。例如,在一个电子商务平台中,买家、卖家和订单管理系统之间可以通过中介者进行协调,从而简化复杂的交互逻辑。
- 多对象共享中介者:当多个对象需要共享同一个中介者时,中介者负责协调这些对象之间的通信。例如,在分布式系统中,中介者可以充当调度中心,协调不同节点的工作。
- GUI系统:在图形用户界面(GUI)系统中,中介者模式可以用来管理各个控件之间的交互。例如,当用户点击某个按钮时,中介者对象负责将这个事件通知给相关的控件,从而触发相应的操作。
- 事件处理系统:在事件处理系统中,中介者对象可以负责协调事件的发布和订阅,确保事件能及时传递给感兴趣的对象。
- 多线程系统:在多线程系统中,中介者模式可以用来协调不同线程之间的交互。例如,当某个线程需要与另一个线程通信时,它只需要通过中介者对象来发送消息,而不需要直接与另一个线程建立连接。
- 分布式系统:在分布式系统中,中介者模式可以用来协调不同组件之间的通信。例如,某个组件需要与另一个组件通信时,它只需要通过中介者对象来发送消息,而不需要直接与另一个组件建立连接。
- MVC架构:在MVC架构中,控制器(Controller)充当模型(Model)和视图(View)之间的中介者,从而降低对象之间的耦合性。
中介者模式的优点包括降低耦合度、提高系统的可维护性和可扩展性。然而,过度使用可能导致中介者对象过于复杂,难以维护和管理。因此,在实际应用中需要谨慎选择其使用时机,并合理划分中介者的职责。
4. 优缺点
-
优点:
- 降低耦合度:中介者模式通过将多个对象的交互封装在中介者中,使得各个对象不再直接相互引用,从而减少了对象间的依赖关系。这种解耦合的设计使得对象可以独立变化和复用,提高了代码的可维护性和灵活性。
- 集中控制:所有的交互逻辑都由中介者集中管理,这使得系统的行为更加清晰,代码维护更为集中。因此,当需要修改系统行为时,只需修改中介者即可,而无需修改其他对象。
- 提高可扩展性:中介者模式允许在不改变现有对象的情况下添加新的对象或行为,只需修改中介者即可实现扩展。这使得系统更容易添加或删除对象,而无需影响其他对象。
- 简化对象交互:中介者模式将复杂的交互逻辑集中在中介者中,使得对象之间的交互变得简单和集中。这有助于简化系统结构,降低系统的复杂度。
- 增强对象的封装性:同事对象只需与中介者通信,不必知道其他同事的存在,从而增强了对象的封装性。
-
缺点:
- 中介者复杂性:随着系统中对象数量的增加,中介者需要处理的逻辑变得复杂,可能导致中介者自身变得难以维护。具体中介者类可能会变得庞大且复杂,难以管理和维护。
- 性能开销:中介者模式引入了一个额外的中介者对象,这可能会增加系统的性能开销。在通信期间需要额外的调度,可能会影响性能。
- 单点故障:中介者模式引入了一个中心化的中介者对象,如果这个中介者出现问题,可能会影响整个系统的功能。这增加了系统的脆弱性。
- 过度依赖中介者:如果设计不当,中介者可能成为系统中的“上帝对象”,承担过多的职责,导致系统难以维护。
- 不适用简单场景:在对象之间的交互相对简单的情况下,使用中介者模式可能会引入不必要的复杂性,增加代码的复杂度。
- 违背开闭原则:当新的同事对象被加入时,可能需要修改中介者对象的代码,这违反了开闭原则。
中介者模式在处理复杂的对象交互场景中具有显著的优势,但在简单场景下可能会显得过于繁琐。因此,在使用中介者模式时,需要根据具体情况权衡其优缺点,确保模式的使用能够带来实际的设计和维护好处。
5. 总结
在实际应用中,中介者模式可以用于管理复杂的系统结构,如聊天室、游戏开发中的角色和事件管理等。例如,在一个聊天系统中,每个用户通过中介者对象发送和接收消息,而不是直接与其他用户通信,从而简化了系统的交互逻辑。
中介者模式通过引入一个中介者对象来封装对象间的交互逻辑,使得系统结构更加松散耦合和易于维护。然而,在使用该模式时需要谨慎处理中介者的职责分配,以确保系统的稳定性和可维护性。
相关文章:
23种设计模式之中介者模式
目录 1. 简介2. 代码2.1 Mediator (中介者接口)2.2 ChatRoom (具体中介者类)2.3 User (同事接口)2.4 ChatUser (具体同事类)2.5 Test (测试)2.6 运行结果 3. …...

【Golang】Go语言编程思想(六):Channel,第六节,并发编程模式
并发模式 下例重新对 channel 的用法进行回顾: package mainimport ("fmt""math/rand""time" )func msgGen(name string) chan string {c : make(chan string)go func(name string) { // 在这个 goroutine 当中向外发送数据i : 0fo…...

unity打包web,如何减小文件体积,特别是 Build.wasm.gz
unity打包WebGL,使用的是wasw,最终生成的Build.wasm.gz体积很大,有6.5M,有几个方法可以稍微减小这个文件的大小 1. 裁剪引擎代码: 此步可将大小从6.5减小到 6.2(此项默认开启,只是改了裁剪等级…...

go引入skywalking
前置条件:安装好jdk11,linux服务器(centos7.9),go版本(我的是1.18,1.21都可以) 1.下载skywalking Downloads | Apache SkyWalking 2.下载agent源码 Downloads | Apache SkyWalkin…...
大华DSS数字监控系统 attachment_downloadAtt.action 任意文件下载漏洞复现
0x01 产品描述: 大华 DSS 数字监控系统是大华开发的一款安防视频监控系统,拥有实时监视、云台操作、录像回放、报警处理、设备管理等功能。0x02 漏洞描述: 大华DSS数字监控系统 attachment_downloadAtt.action接口存在任意文件读取漏洞,未经身份验证攻击者可通过该漏洞读取…...

qt 封装 调用 dll
这个目录下 ,第一个收藏的这个 ,可以用, 但是有几个地方要注意 第一.需要将dll的头文件添加到qt的文件夹里面 第二,需要在pro文件里面添加动态库路径 第三,如果调用dll失败,那么大概需要将dll文件放在e…...

Python使用Selenium库获取 网页节点元素、名称、内容的方法
我们要用到一些网页源码信息,例如获取一些节点的class内容, 除了使用Beautifulsoup来解析,还可以直接用Selenium库打印节点(元素)名称,用来获取元素的文本内容或者标签名。 例如获取下面的class的内容&am…...

系统安全——访问控制访问控制
访问控制 概念 什么是访问控制 access control 为用户对系统资源提供最大限度共享的基础上,对用户的访问权进行管理,防止对信息的非授权篡改和滥用 访问控制作用 保证用户在系统安全策略下正常工作 拒绝非法用户的非授权访问请求 拒绝合法用户越权…...
SQL Server 数据库还原到某个时点(完整恢复模式)
将 SQL Server 数据库还原到某个时点(完整恢复模式) 适用范围: SQL Server 本主题介绍如何使用 SQL Server Management Studio 或 Transact-SQL 将数据库还原到 SQL Server 中的某个时间点。 本主题仅与使用完整恢复模式或大容量日志恢复模…...

埃隆马斯克X-AI发布Grok-2大模型,快来体验~
引言 近年来,人工智能技术的快速发展推动了大语言模型的广泛应用。无论是日常生活中的智能助手,还是行业中的自动化解决方案,大语言模型都扮演着越来越重要的角色。2024年,X-AI推出了新一代的大模型——Grok-2,这款模…...
Python工厂设计模式:简化对象创建
Python工厂设计模式:简化对象创建 引言什么是工厂模式?简单工厂模式示例定义基类和子类创建工厂类使用工厂创建对象 优点使用场景总结 引言 在编程中,我们经常需要创建不同的对象,但有时创建对象的逻辑可能会变得复杂。工厂设计模…...

【隐私计算篇】隐私集合求交(PSI)原理深入浅出
隐私集合求交技术是多方安全计算领域的一个子问题,通常也被称为安全求交、隐私保护集合交集或者隐私交集技术等,其目的是允许持有各自数据集的双方或者多方,执行两方或者多方集合的交集计算,当PSI执行完成,一方或者两方…...
工作中常用的8种设计模式
前言 设计模式在我们日常的软件开发中无处不在,它们帮助我们编写更易扩展、更具可读性的代码。 今天结合我实际工作场景和源码实例,跟大家一起聊聊工作中最常用的8种设计模式,希望对你会有所帮助。 1. 单例模式 单例模式确保一个类只有一…...

Qwen 论文阅读记录
本文仅作自己初步熟悉大模型,梳理之用,慢慢会更改/增加/删除,部分细节尚未解释,希望不断学习之后,能够完善补充。若有同道之人,欢迎指正探讨。 关于后面的code-qwen and math-qwen,我个人认为依…...
自动驾驶:百年演进
亲爱的小伙伴们😘,在求知的漫漫旅途中,若你对深度学习的奥秘、JAVA 、PYTHON与SAP 的奇妙世界,亦或是读研论文的撰写攻略有所探寻🧐,那不妨给我一个小小的关注吧🥰。我会精心筹备,在…...

SSM 校园一卡通密钥管理系统 PF 于校园图书借阅管理的安全保障
摘 要 传统办法管理信息首先需要花费的时间比较多,其次数据出错率比较高,而且对错误的数据进行更改也比较困难,最后,检索数据费事费力。因此,在计算机上安装校园一卡通密钥管理系统软件来发挥其高效地信息处理的作用&a…...
什么叫中间件服务器?
什么叫中间件服务器?它在软件架构中扮演着怎样的角色?在现代应用程序开发中,中间件服务器的概念很多人对它并不太熟悉,但其实它的作用却不小。 中间件服务器是一种连接不同软件应用程序的中介。想象一下,在一个大型企…...

【docker】12. Docker Volume(存储卷)
什么是存储卷? 存储卷就是将宿主机的本地文件系统中存在的某个目录直接与容器内部的文件系统上的某一目录建立绑定关系。这就意味着,当我们在容器中的这个目录下写入数据时,容器会将其内容直接写入到宿主机上与此容器建立了绑定关系的目录。 在宿主机上…...

SpringBoot【八】mybatis-plus条件构造器使用手册!
一、前言🔥 环境说明:Windows10 Idea2021.3.2 Jdk1.8 SpringBoot 2.3.1.RELEASE 经过上一期的mybatis-plus 入门教学,想必大家对它不是非常陌生了吧,这期呢,我主要是围绕以下几点展开,重点给大家介绍 里…...

OpenAI直播发布第4天:ChatGPT Canvas全面升级,免费开放!
大家好,我是木易,一个持续关注AI领域的互联网技术产品经理,国内Top2本科,美国Top10 CS研究生,MBA。我坚信AI是普通人变强的“外挂”,专注于分享AI全维度知识,包括但不限于AI科普,AI工…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...

Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...

uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...

《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...