设计模式: 行为型之中介者模式(18)
中介者模式概述
- 中介者模式(Mediator Pattern)是一种行为设计模式,它用于减少对象之间的直接交互,从而使其可以松散耦合
- 中介者模式通过引入一个中介者对象来协调多个对象之间的交互,使得这些对象不需要知道彼此的具体实现,只需与中介者进行通信
- 中介者模式结构
- 中介者(Mediator)
- 定义了一个接口,用于与各同事对象通信
- 具体中介者(ConcreteMediator)
- 实现中介者接口,协调各个同事对象之间的交互
- 并可以维护同事对象之间的引用关系
- 同事类(Colleague)
- 每一个同事对象都知道中介者对象,并与它通信
- 但不知道其他同事对象,同事对象之间的交互通过中介者对象来完成
- 中介者(Mediator)
中介者模式应用
// 1. 定义同事类(Colleague)接口
interface Colleague {mediator: Mediator;send(message: string): void;receive(message: string): void;
}// 2. 定义中介者(Mediator)接口
interface Mediator {register(colleague: Colleague): void;sendMessage(sender: string, message: string): void;
}// 3. 创建具体同事类
class ConcreteColleagueA implements Colleague {mediator: Mediator;name: string;constructor(name: string, mediator: Mediator) {this.mediator = mediator;this.name = name;}send(message: string): void {this.mediator.sendMessage(this.name, message);}receive(message: string): void {console.log(`${this.name} received the message: ${message}`);}
}class ConcreteColleagueB implements Colleague {mediator: Mediator;name: string;constructor(name: string, mediator: Mediator) {this.mediator = mediator;this.name = name;}send(message: string): void {this.mediator.sendMessage(this.name, message);}receive(message: string): void {console.log(`${this.name} received the message: ${message}`);}
}// 4. 创建具体中介者类
class ConcreteMediator implements Mediator {private colleagues: Colleague[] = [];register(colleague: Colleague): void {this.colleagues.push(colleague);}sendMessage(sender: string, message: string): void {this.colleagues.forEach(colleague => {if (colleague.name !== sender) {colleague.receive(message);}});}
}// 使用示例
function main() {const mediator = new ConcreteMediator();const colleagueA = new ConcreteColleagueA("Colleague A", mediator);const colleagueB = new ConcreteColleagueB("Colleague B", mediator);mediator.register(colleagueA);mediator.register(colleagueB);colleagueA.send("Hello from A");colleagueB.send("Hello from B");
}main();
- 首先,我们定义了两个接口:
Colleague
和Mediator
Colleague
接口表示参与交互的对象,它有两个方法:send
用于发送消息,receive
用于接收消息- 并且有一个属性
mediator
,指向中介者对象。Mediator
接口则定义了中介者应当具备的能力,包括注册同事对象(register
)和转发消息(sendMessage
)
- 我们创建了两个实现了
Colleague
接口的具体同事类ConcreteColleagueA
和ConcreteColleagueB
- 每个具体同事类都有自己的名字,并且持有中介者对象
- 当它们想要发送消息时,通过调用中介者的
sendMessage
方法而非直接和其他同事类通信
- 实现了
Mediator
接口的ConcreteMediator
类是具体的中介者- 它维护了一个同事对象列表,并提供
register
方法用于同事对象的注册 - 当一个同事对象通过
sendMessage
发送消息时,中介者会遍历同事列表,将消息转发给除了发送者之外的所有同事对象
- 它维护了一个同事对象列表,并提供
- 在
main
函数中,我们创建了一个ConcreteMediator
对象作为中介者,并创建了两个同事对象(ConcreteColleagueA
和ConcreteColleagueB
)- 接着,我们把这两个同事对象注册到中介者,并让每个同事对象发送一条消息
- 此时,消息通过中介者转发,确保每个同事都能收到除自己发送之外的消息
- 通过这个示例,我们可以看到中介者模式是如何解耦同事对象之间直接的通信关系,转而通过中介者来进行消息传递,从而降低了耦合度,增强了系统的可维护性和扩展性
中介者模式应用场景
-
对象间的交互复杂:当系统中有多个对象相互协作,且它们之间的交互关系错综复杂,表现为网状结构或多对多关系时,可以使用中介者模式来集中管理这些交互,将原来分散在各个对象之间的交互逻辑转移到中介者中,从而简化对象间的直接依赖关系
-
需要解耦对象:当发现系统中对象彼此之间的依赖性过高,修改一个对象可能引起一系列连锁反应时,通过中介者模式可以使对象之间的耦合度降低,提高系统的可维护性和扩展性
-
通信逻辑需要集中控制:在一些场景中,如网络聊天室、飞行控制系统、游戏引擎中的实体交互、UI组件间通信等,需要有一个中心对象来管理和协调不同对象间的通信,这些场景非常适合采用中介者模式
-
易于扩展新功能:当系统中未来可能增加更多参与者(对象)或者改变交互规则时,通过中介者模式可以相对容易地调整和扩展通信逻辑,因为大部分交互都在中介者内完成,不涉及其他对象的改动
-
需要支持模块化:在大型软件系统中,中介者模式可以帮助将系统划分为可独立开发和测试的模块,每个模块作为一个对象与中介者交互,而模块间的复杂交互则通过中介者来组织和协调
-
总之,中介者模式尤其适用于那些对象间交互繁杂,且希望避免对象之间紧密耦合的场景,通过引入中介者,可以将复杂的交互关系转化为中介者与各个对象之间的简单交互
中介者模式优缺点
1 ) 优点
-
降低对象之间的耦合度:同事对象之间不再直接相互调用,而是通过中介者来间接通信,减少了它们之间的耦合
-
易于维护:由于将对象之间的交互逻辑集中到了中介者对象中,因此如果需要修改交互方式,只需修改中介者即可,而无需修改所有同事对象
-
简化对象之间的通信:同事对象不再需要知道其他对象的存在,只需与中介者通信,降低了通信的复杂性
-
支持灵活的通信方式:中介者可以根据需要实现不同的通信策略,比如广播、单播等
2 )缺点
-
可能产生过多的中介者:如果系统中存在过多的中介者,可能会导致系统结构变得复杂
-
中介者可能变得过于复杂:如果中介者需要处理大量的同事对象之间的交互,其内部逻辑可能会变得相当复杂,难以维护
-
可能引入新的依赖:同事对象依赖于中介者,如果中介者出现问题,可能会影响到多个同事对象的正常工作
-
在使用中介者模式时,需要根据具体场景和需求权衡其优缺点,确保在降低耦合度和简化通信的同时,避免引入过多的复杂性和依赖关系
中介者模式和代理模式区别和联系
- 中介者模式(Mediator Pattern)和代理模式(Proxy Pattern)都是设计模式中的行为型模式,它们在解决软件设计问题上有不同的侧重点和应用场景
1 )中介者模式
-
目的: 解决对象之间的多重关联和通信复杂性问题,通过引入中介者对象来封装对象间的交互逻辑,使得原本相互耦合的对象转变为与中介者对象的单向关联,从而降低对象之间的耦合度。
-
角色: 同事类(Colleague)、中介者(Mediator)
-
作用: 中介者对象集中处理同事类之间的交互,同事类只与中介者交互,不直接与其他同事类交互。
-
适用场景: 多个对象之间存在复杂的网状交互,如聊天室的消息路由、组件间的通信协调等
2 )代理模式
- 目的: 为其他对象提供一个代理,以控制对这个对象的访问,增强或扩展功能,如延迟加载、安全性控制、访问权限控制、远程代理、虚拟代理等。
- 角色: 主题(Subject)、代理(Proxy)、真实主题(Real Subject)
- 作用: 代理对象替代真实对象,对外提供相同的接口,但可以在调用前后附加额外的操作,比如缓存、预处理、后处理、权限检查等。
- 适用场景: 需要控制访问、增强功能、保护目标对象或透明地添加额外操作等场合,如数据库连接池、图片懒加载、远程服务调用等。
3 )区别与联系
- 区别
- 目的不同:中介者模式主要用于解耦对象间的复杂交互,而代理模式主要用于控制对对象的访问
- 结构不同:中介者模式中对象与中介者单向交互,代理模式中代理与真实对象的接口一致,代理对象代替或辅助真实对象工作
- 作用不同:中介者模式改变了对象间的通信结构,代理模式通常不会改变对象间的结构,只是在访问过程中增加了额外的逻辑
- 联系
- 都属于行为型设计模式,都通过引入中间层对象来改善原有对象结构和行为
- 都是对对象功能的一种包装和扩展,只不过中介者模式更关注于整体的交互协调,而代理模式更侧重于个体对象的访问控制和功能扩展
- 在实际开发中,这两种模式经常结合使用,共同优化系统的架构和设计
相关文章:
设计模式: 行为型之中介者模式(18)
中介者模式概述 中介者模式(Mediator Pattern)是一种行为设计模式,它用于减少对象之间的直接交互,从而使其可以松散耦合中介者模式通过引入一个中介者对象来协调多个对象之间的交互,使得这些对象不需要知道彼此的具体…...
计算机网络的起源与发展历程
文章目录 前言时代背景ARPANET 的诞生TCP/IP 协议簇与 Internet 的诞生HTTP 协议与 Web 世界结语 前言 在当今数字化时代,计算机网络已经成为我们生活中不可或缺的一部分。无论是在家庭、学校、还是工作场所,我们都能感受到网络的巨大影响。随着互联网的…...
2024-4-12-实战:商城首页(下)
个人主页:学习前端的小z 个人专栏:HTML5和CSS3悦读 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结,欢迎大家在评论区交流讨论! 文章目录 作业小结 作业 .bg-backward {width: 60px; height: 60px;background: url(..…...
一、flask入门和视图
run启动参数 模板渲染 后端给前端页面传参 前端页面设置css from flask import Flask, render_template,jsonify# 创建flask对象 app Flask(__name__)# 视图函数 路由route app.route("/") def hello_world():# 响应,返回给前端的数据return "h…...
Selenium+Chrome Driver 爬取搜狐页面信息
进行selenium包和chromedriver驱动的安装 安装selenium包 在命令行或者anaconda prompt 中输入 pip install Selenium 安装 chromedriver 先查看chrome浏览器的版本 这里是 123.0.6312.106 版 然后在http://npm.taobao.org/mirrors/chromedriver/或者https://googlechrom…...
SpringBoot:一个注解就能帮你下载任意对象
介绍 下载功能应该是比较常见的功能了,虽然一个项目里面可能出现的不多,但是基本上每个项目都会有,而且有些下载功能其实还是比较繁杂的,倒不是难,而是麻烦。 所以结合之前的下载需求,我写了一个库来简化…...
oracle全量、增量备份
采用0221222增量备份策略,7天一个轮回 也就是周日0级备份,周1 2 4 5 6 采用2级增量备份,周3采用1级增量备份 打开控制文件自动备份 CONFIGURE CONTROLFILE AUTOBACKUP ON; 配置控制文件备份路径 CONFIGURE CONTROLFILE AUTOBACKUP FORMAT FOR DEVI…...
React Router 5 vs 6:使用上的主要差异与升级指南
React Router 5 的一些API 在 React Router 6 上有时可能找不到,可能会看到如下画面:export ‘useHistory’ was not found in ‘react-router-dom’ … React Router目前有两个大的版本,即React Router 5、6。React Router 6 在设计上更加简…...
基于LNMP部署wordpress
目录 一.环境准备 二.配置源并安装 三.配置Nginx 四.配置数据库 五.上传源码并替换 六.打开浏览器,输入虚拟机ip访问安装部署 七.扩展增加主题 一.环境准备 centos7虚拟机 关闭防火墙和seliunx stop firewalld #关闭防火墙 setenforce 0 …...
openGauss_5.1.0 企业版快速安装及数据库连接:单节点容器化安装
目录 📚第一章 官网信息📚第二章 安装📗下载源码📗下载安装包📗修改版本📗解压安装包📗运行buildDockerImage.sh脚本📗docker操作📕查看docker镜像📕启动dock…...
微信小程序 uniapp+vue城市公交线路查询系统dtjl3
小程序Android端运行软件 微信开发者工具/hbuiderx uni-app框架:使用Vue.js开发跨平台应用的前端框架,编写一套代码,可编译到Android、小程序等平台。 前端:HTML5,CSS3 VUE 后端:java(springbootssm)/python(flaskdja…...
2024年MathorCup数模竞赛B题问题一二三+部分代码分享
inputFolderPath E:\oracle\images\; outputFolderPath E:\oracle\process\; % 获取文件夹中所有图片的文件列表 imageFiles dir(fullfile(inputFolderPath, *.jpg)); % 设置colorbar范围阈值 threshold 120; % 遍历每个图片文件 for i 1:length(imageFiles) % 读…...
Ubuntu日常配置
目录 修改网络配置 xshell连不上怎么办 解析域名失败 永久修改DNS方法 临时修改DNS方法 修改网络配置 1、先ifconfig确认本机IP地址(刚装的机子没有ifconfig,先apt install net-tools) 2、22.04版本的ubuntu网络配置在netplan目录下&…...
GMSSL-通信
死磕GMSSL通信-C/C++系列(一) 最近再做国密通信的项目开发,以为国密也就简单的集成一个库就可以完事了,没想到能有这么多坑。遂写下文章,避免重复踩坑。以下国密通信的坑有以下场景 1、使用GMSSL guanzhi/GmSSL进行通信 2、使用加密套件SM2-WITH-SMS4-SM3 使用心得 …...
linux 磁盘分区Inode使用率达到100%,导致网站无法创建文件报错 failed:No space leftondevice(
linux 磁盘分区Inode使用率达到100%,导致网站无法创建文件报错 failed:No space left on device 由于这问题直接导致了,网站无法正常运行! 提交工单求助阿里后,得到了答案! 工程师先让我执行 df -h 和 df -i 通过分析…...
探索Python库的奇妙世界
探索Python库的奇妙世界 Python作为一种流行的编程语言,因其简洁的语法、强大的库支持和广泛的应用场景而备受开发者青睐。在这篇文章中,我们将深入探讨Python库的世界,了解它们如何帮助我们更高效地编写代码,并展示一些最有用的…...
SQL Server 存储函数(funGetId):唯一ID
系统测试时批量生成模拟数据,通过存储函数生成唯一ID。 根据当前时间生成唯一ID(17位) --自定义函数:根据当前时间组合成一个唯一ID字符串:yearmonthdayhourminutesecondmillisecond drop function funGetId;go--自定义函数&…...
当你的项目体积比较大?你如何做性能优化
在前端开发中,项目体积优化是一个重要的环节,它直接影响到网页的加载速度和用户体验。随着前端项目越来越复杂,引入的依赖也越来越多,如何有效地减少最终打包文件的大小,成为了前端工程师需要面对的挑战。以下是一些常…...
第6章:6.3.2 一张表总结正则表达式的语法 (MATLAB入门课程)
讲解视频:可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。 MATLAB教程新手入门篇(数学建模清风主讲,适合零基础同学观看)_哔哩哔哩_bilibili 本节我们用一张表来回顾和总结MATLAB正则表达式的基本语法。这个…...
VBA 实现outlook 当邮件设置category: red 即触发自动创建jira issue
1. 打开: Outlook VBA(Visual Basic for Applications) 方法一: 在邮件直接搜索:Visual Basic editor 方法二: File -> Options -> Customize Ribbon-> 打钩 如下图: 2.设置运行VBA 脚本: File -> Options -> Trust center -> Trus…...
办公软件巨头CCED、WPS迎来新挑战,新款办公软件已形成普及之势
办公软件巨头CCED、WPS的成长经历 CCED与WPS,这两者均是中国办公软件行业的佼佼者,为人们所熟知。 然而,它们的成功并非一蹴而就,而是经过了长时间的积累与沉淀。 CCED,这款中国大陆早期的文本编辑器,在上…...
架构设计-订单系统之订单系统的架构进化
1、单数据库架构 产品初期,技术团队的核心目标是:“快速实现产品需求,尽早对外提供服务”。 彼时的专车服务都连同一个 SQLServer 数据库,服务层已经按照业务领域做了一定程度的拆分。 这种架构非常简单,团队可以分开…...
性能升级,INDEMIND机器人AI Kit助力产业再蜕变
随着机器人进入到越来越多的生产生活场景中,作业任务和环境变得更加复杂,机器人需要更精准、更稳定、更智能、更灵敏的自主导航能力。 自主导航技术作为机器人技术的核心,虽然经过了多年发展,取得了长足进步,但在实践…...
2024年妈妈杯数学建模C题思路分析-物流网络分拣中心货量预测及人员排班
# 1 赛题 C 题 物流网络分拣中心货量预测及人员排班 电商物流网络在订单履约中由多个环节组成,图 ’ 是一个简化的物流 网络示意图。其中,分拣中心作为网络的中间环节,需要将包裹按照不同 流向进行分拣并发往下一个场地,最终使包裹…...
prometheus\skywalking\splunk功能的区别
Prometheus、SkyWalking和Splunk这三个工具在功能上各有特色,以下是它们各自的主要功能特点: Prometheus是一个开源的系统监控和警报工具。它的主要功能包括: 实时监控与警报:Prometheus可以实时监控各种指标,并根据…...
Harmony鸿蒙南向驱动开发-SPI接口使用
功能简介 SPI指串行外设接口(Serial Peripheral Interface),是一种高速的,全双工,同步的通信总线。SPI是由Motorola公司开发,用于在主设备和从设备之间进行通信。 SPI接口定义了操作SPI设备的通用方法集合…...
芒果YOLOv7改进96:检测头篇DynamicHead动态检测头:即插即用|DynamicHead检测头,尺度感知、空间感知、任务感知
该专栏完整目录链接: 芒果YOLOv7深度改进教程 该创新点:在原始的Dynamic Head的基础上,对核心部位进行了二次的改进,在 原论文 《尺度感知、空间感知、任务感知》 的基础上,在 通道感知 的层级上进行了增强,关注每个像素点的比重。 在自己的数据集上改进,有效涨点就可以…...
独一无二:探索单例模式在现代编程中的奥秘与实践
设计模式在软件开发中扮演着至关重要的角色,它们是解决特定问题的经典方法。在众多设计模式中,单例模式因其独特的应用场景和简洁的实现而广受欢迎。本文将从多个角度详细介绍单例模式,帮助你理解它的定义、实现、应用以及潜在的限制。 1. 什…...
centos7 安装 rabbitmq3.8.5
1.首先安装 erlang 环境: curl -s https://packagecloud.io/install/repositories/rabbitmq/erlang/script.rpm.sh | sudo bash sudo yum install erlang-21.3.8.14-1.el7.x86_64 yum install socat -y 2.安装 rabbitmq https://github.com/rabbitmq/rabbitmq-s…...
利用SOCKS5代理和代理IP提升网络安全与匿名性
一、引言 随着网络技术的迅猛发展,数据安全和隐私保护已成为业界关注的热点。企业和个人用户越来越依赖于各种网络技术来保护敏感信息免受未授权访问。本文将探讨SOCKS5代理、代理IP以及HTTP协议在提升网络安全和匿名性方面的作用和实践应用。 二、基础技术概述 2.…...
ih5网站制作平台/百度首页百度一下
用oracle sql对数字进行操作: 取上取整、向下取整、保留N位小数、四舍五入、数字格式化取整(向下取整): select floor(5.534) from dual;select trunc(5.534) from dual;上面两种用法都可以对数字5.534向下取整,结果为5. 如果要向…...
delphi xe10网站开发/搜索数据
直接上代码… /*** author gxq* date * <p>* 自定义注解(实现数据库查询,接口访问权限一系列)*/ Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE}) //表示此作用作用的目标&…...
phpcms 怎么做视频网站首页/微信软文范例100字
抱歉,这个问题太幼稚了,但对于我在该主题上的经历也是如此.从谷歌搜索我所了解的内容,我只是想确认该理解是正确的.欢迎大家查明我错了.> OCI基本上是一组API,供C/C程序员用来编写C/C应用程序访问Oracle数据库.> a)Oracle Instant Client SDK是使用OCI(???)的(DLL /共…...
做软件用什么软件/搜索引擎优化方法包括
通常,在WEB系统中,上传文件时都需要做文件的类型校验,大致有如下几种方法: 1. 通过后缀名,如exe,jpg,bmp,rar,zip等等。 2. 通过读取文件,获取文件的Content-type来判断。 3. 通过读取文件流,根…...
新公司名字注册查询/教程推广优化网站排名
使用领域模型,很少会像创建实际领域模型类、然后使用它们那么简单。很快你就会发现,领域模型必须得到相当数量的基础架构代码的支持。 领域模型所需基础架构当中最显著的当然是持久化——通常是持久化到关系型数据库中,也就是对象/关系&#…...
wordpress 末班/nba最新交易
2019独角兽企业重金招聘Python工程师标准>>> 我们想要添加一个文件到Cocos2d-x的目录下,一般有两种方式: 第一种 在导航栏点击右键,选择Add files to 第二种 直接将文件拖拽进来。 但是无论哪种方式,我们都会面临一个&…...