瑞_23种设计模式_中介者模式
文章目录
- 1 中介者模式(Mediator Pattern)
- 1.1 介绍
- 1.2 概述
- 1.3 中介者模式的结构
- 1.4 中介者模式的优缺点
- 1.5 中介者模式的使用场景
- 2 案例一
- 2.1 需求
- 2.2 代码实现
- 3 案例二
- 3.1 需求
- 3.2 代码实现
🙊 前言:本文章为瑞_系列专栏之《23种设计模式》的中介者模式篇。本文中的部分图和概念等资料,来源于博主学习设计模式的相关网站《菜鸟教程 | 设计模式》和《黑马程序员Java设计模式详解》,特此注明。本文中涉及到的软件设计模式的概念、背景、优点、分类、以及UML图的基本知识和设计模式的6大法则等知识,建议阅读 《瑞_23种设计模式_概述》
本系列 - 设计模式 - 链接:《瑞_23种设计模式_概述》
⬇️本系列 - 创建型模式 - 链接🔗单例模式:《瑞_23种设计模式_单例模式》
工厂模式:《瑞_23种设计模式_工厂模式》
原型模式:《瑞_23种设计模式_原型模式》
抽象工厂模式:《瑞_23种设计模式_抽象工厂模式》
建造者模式:《瑞_23种设计模式_建造者模式》⬇️本系列 - 结构型模式 - 链接🔗
代理模式:《瑞_23种设计模式_代理模式》
适配器模式:《瑞_23种设计模式_适配器模式》
装饰者模式:《瑞_23种设计模式_装饰者模式》
桥接模式:《瑞_23种设计模式_桥接模式》
外观模式:《瑞_23种设计模式_外观模式》
组合模式:《瑞_23种设计模式_组合模式》
享元模式:《瑞_23种设计模式_享元模式》⬇️本系列 - 行为型模式 - 链接🔗
模板方法模式:《瑞_23种设计模式_模板方法模式》
策略模式:《瑞_23种设计模式_策略模式》
命令模式:《瑞_23种设计模式_命令模式》
职责链模式:《瑞_23种设计模式_职责链模式》
状态模式:《瑞_23种设计模式_状态模式》
观察者模式:《瑞_23种设计模式_观察者模式》
中介者模式:《后续更新》
迭代器模式:《后续更新》
访问者模式:《后续更新》
备忘录模式:《后续更新》
解释器模式:《后续更新》
1 中介者模式(Mediator Pattern)
瑞:中介者模式在框架设计中经常使用,即使框架内部再复杂,其使用方法也会相对简单。如Spring框架中的 BeanFactory 就是中介者模式的一个实现,它作为中介者,负责管理和创建应用程序中的所有 beans ,而不是让 beans 直接相互引用或创建。
中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性。这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护。中介者模式属于行为型模式。
瑞:行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。
瑞:行为型模式分为类行为模式和对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。
中介者模式属于:对象行为模式
1.1 介绍
-
意图:用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
-
主要解决:对象与对象之间存在大量的关联关系,这样势必会导致系统的结构变得很复杂,同时若一个对象发生改变,我们也需要跟踪与之相关联的对象,同时做出相应的处理。
-
何时使用:多个类相互耦合,形成了网状结构。
-
如何解决:将上述网状结构分离为星型结构。
-
关键代码:对象 Colleague 之间的通信封装到一个类中单独处理。
-
应用实例:
1️⃣ 中国加入 WTO 之前是各个国家相互贸易,结构复杂,现在是各个国家通过 WTO 来互相贸易。
2️⃣ 机场调度系统。
3️⃣ MVC 框架,其中C(控制器)就是 M(模型)和 V(视图)的中介者。 -
优点:
1️⃣ 降低了类的复杂度,将一对多转化成了一对一。
2️⃣ 各个类之间的解耦。
3️⃣ 符合迪米特原则。 -
缺点:
1️⃣ 中介者会庞大,变得复杂难以维护。 -
使用场景:
1️⃣ 系统中对象之间存在比较复杂的引用关系,导致它们之间的依赖关系结构混乱而且难以复用该对象。
2️⃣ 想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。 -
注意事项:
1️⃣ 不应当在职责混乱的时候使用
1.2 概述
定义:中介者模式又叫调停模式,定义一个中介角色来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。
一般来说,同事类之间的关系是比较复杂的,多个同事类之间互相关联时,他们之间的关系会呈现为复杂的网状结构,这是一种过度耦合的架构,即不利于类的复用,也不稳定。例如在下左图中,有六个同事类对象,假如对象1发生变化,那么将会有4个对象受到影响。如果对象2发生变化,那么将会有5个对象受到影响。也就是说,同事类之间直接关联的设计是不好的。
如果引入中介者模式,那么同事类之间的关系将变为星型结构,从下图中可以看到,任何一个类的变动,只会影响的类本身,以及中介者,这样就减小了系统的耦合。一个好的设计,必定不会把所有的对象关系处理逻辑封装在本类中,而是使用一个专门的类来管理那些不属于自己的行为。
1.3 中介者模式的结构
- 中介者模式主要包含以下角色:
1️⃣ Subject:抽象中介者(Mediator)角色:它是中介者的接口,提供了同事对象注册与转发同事对象信息的抽象方法。
2️⃣ 具体中介者(ConcreteMediator)角色:实现中介者接口,定义一个 List 来管理同事对象,协调各个同事角色之间的交互关系,因此它依赖于同事角色。
3️⃣ 抽象同事类(Colleague)角色:定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。
4️⃣ 具体同事类(Concrete Colleague)角色:是抽象同事类的实现者,当需要与其他同事对象交互时,由中介者对象负责后续的交互。
1.4 中介者模式的优缺点
优点:
-
松散耦合
中介者模式通过把多个同事对象之间的交互封装到中介者对象里面,从而使得同事对象之间松散耦合,基本上可以做到互补依赖。这样一来,同事对象就可以独立地变化和复用,而不再像以前那样“牵一处而动全身”了。 -
集中控制交互
多个同事对象的交互,被封装在中介者对象里面集中管理,使得这些交互行为发生变化的时候,只需要修改中介者对象就可以了,当然如果是已经做好的系统,那么就扩展中介者对象,而各个同事类不需要做修改。 -
一对多关联转变为一对一的关联
没有使用中介者模式的时候,同事对象之间的关系通常是一对多的,引入中介者对象以后,中介者对象和同事对象的关系通常变成双向的一对一,这会让对象的关系更容易理解和实现。
缺点:
- 当同事类太多时,中介者的职责将很大,它会变得复杂而庞大,以至于系统难以维护。
1.5 中介者模式的使用场景
- 系统中对象之间存在复杂的引用关系,系统结构混乱且难以理解。
- 当想创建一个运行于多个类之间的对象,又不想生成新的子类时。
2 案例一
【案例】租房
2.1 需求
现在租房基本都是通过房屋中介,房主将房屋托管给房屋中介,而租房者从房屋中介获取房屋信息。房屋中介充当租房者与房屋所有者之间的中介者。
类图如下:
2.2 代码实现
/*** 抽象中介者类** @author LiaoYuXing-Ray**/
public abstract class Mediator {// 沟通public abstract void contact(String message, Person person);
}
/*** 抽象同事类** @author LiaoYuXing-Ray**/
public abstract class Person {// 租房者或者房主的姓名protected String name;// 中介protected Mediator mediator;public Person(String name, Mediator mediator) {this.name = name;this.mediator = mediator;}
}
/*** 具体的同事角色类** @author LiaoYuXing-Ray**/
public class HouseOwner extends Person {public HouseOwner(String name, Mediator mediator) {super(name, mediator);}// 和中介联系(沟通)public void contact(String message) {mediator.contact(message,this);}// 获取信息public void getMessage(String message) {System.out.println("房主" + name + "获取到的信息是:" + message);}
}
/*** 具体的同事角色类** @author LiaoYuXing-Ray**/
public class Tenant extends Person {public Tenant(String name, Mediator mediator) {super(name, mediator);}// 和中介联系(沟通)public void contact(String message) {mediator.contact(message,this);}// 获取信息public void getMessage(String message) {System.out.println("租房者" + name + "获取到的信息是:" + message);}
}
/*** 具体的中介者角色类** @author LiaoYuXing-Ray**/
public class MediatorStructure extends Mediator {// 聚合房主和租房者对象private HouseOwner houseOwner;private Tenant tenant;public HouseOwner getHouseOwner() {return houseOwner;}public void setHouseOwner(HouseOwner houseOwner) {this.houseOwner = houseOwner;}public Tenant getTenant() {return tenant;}public void setTenant(Tenant tenant) {this.tenant = tenant;}public void contact(String message, Person person) {if(person == houseOwner) {tenant.getMessage(message);} else {houseOwner.getMessage(message);}}
}
/*** 测试类** @author LiaoYuXing-Ray**/
public class Client {public static void main(String[] args) {// 创建中介者对象MediatorStructure mediator = new MediatorStructure();// 创建租房者对象Tenant tenant = new Tenant("李四",mediator);// 创建房主对象HouseOwner houseOwner = new HouseOwner("张三",mediator);// 中介者要知道具体的房主和租房者mediator.setTenant(tenant);mediator.setHouseOwner(houseOwner);tenant.contact("要租三室的房子!!!");houseOwner.contact("我这里有三室的房子,你要租吗?");}
}
代码运行结果如下:
房主张三获取到的信息是:要租三室的房子!!!租房者李四获取到的信息是:我这里有三室的房子,你要租吗?
3 案例二
本案例为菜鸟教程中的案例
3.1 需求
我们通过聊天室实例来演示中介者模式。实例中,多个用户可以向聊天室发送消息,聊天室向所有的用户显示消息。我们将创建两个类 ChatRoom 和 User。User 对象使用 ChatRoom 方法来分享他们的消息。
MediatorPatternDemo,我们的演示类使用 User 对象来显示他们之间的通信。
3.2 代码实现
步骤 1
创建中介类。
import java.util.Date;public class ChatRoom {public static void showMessage(User user, String message){System.out.println(new Date().toString()+ " [" + user.getName() +"] : " + message);}
}
步骤 2
创建 user 类。
public class User {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}public User(String name){this.name = name;}public void sendMessage(String message){ChatRoom.showMessage(this,message);}
}
步骤 3
使用 User 对象来显示他们之间的通信。
public class MediatorPatternDemo {public static void main(String[] args) {User robert = new User("Robert");User john = new User("John");robert.sendMessage("Hi! John!");john.sendMessage("Hello! Robert!");}
}
步骤 4
执行程序,输出结果:
Thu Jan 31 16:05:46 IST 2013 [Robert] : Hi! John!Thu Jan 31 16:05:46 IST 2013 [John] : Hello! Robert!
如果觉得这篇文章对您有所帮助的话,请动动小手点波关注💗,你的点赞👍收藏⭐️转发🔗评论📝都是对博主最好的支持~
相关文章:

瑞_23种设计模式_中介者模式
文章目录 1 中介者模式(Mediator Pattern)1.1 介绍1.2 概述1.3 中介者模式的结构1.4 中介者模式的优缺点1.5 中介者模式的使用场景 2 案例一2.1 需求2.2 代码实现 3 案例二3.1 需求3.2 代码实现 🙊 前言:本文章为瑞_系列专栏之《2…...
sqlite删除数据表
1.如何删除表 在SQLite中,删除表的SQL语句是DROP TABLE。如果你想要在Python中使用SQLite库(如sqlite3)来删除一个表,你可以按照以下步骤操作: 连接到SQLite数据库。创建一个cursor对象。执行DROP TABLE语句。提交事…...

Spring Boot简介及案例
文章目录 Spring Boot简介以下是一个简单的 Spring Boot Web 应用实例**步骤 1:创建 Spring Boot 项目****步骤 2:编写 RESTful 控制器****步骤 3:配置主类****步骤 4:运行并测试应用** Spring Boot简介 Spring Boot 是一个用于简…...

Learning To Count Everything
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 摘要Abstract文献阅读:学习数一切东西1、研究背景2、提出方法3、模块详细3.1、多尺度特征提取模块3.2、密度预测模块 4、损失函数5、性能对比6、贡献 二…...

大语言模型(LLM)token解读
1. 什么是token? 人们经常在谈论大模型时候,经常会谈到模型很大,我们也常常会看到一种说法: 参数会让我们了解神经网络的结构有多复杂,而token的大小会让我们知道有多少数据用于训练参数。 什么是token?比…...

【Micro 2014】NoC Architectures for Silicon Interposer Systems
NoC Architectures for Silicon Interposer Systems 背景和动机 硅中介层 主要内容 基于interposer的多核 NOC架构 试验评估 方法 NoC Architectures for Silicon Interposer Systems Natalie Enright Jerger, University of Toronto Gabriel H. Loh AMD Research 硅中介层…...
《极客时间 - 左耳听风》01 | 程序员如何用技术变现?(上)【文章笔记 + 个人思考】
《极客时间 - 左耳听风》 原文链接 :https://time.geekbang.org/column/intro/100002201?tabcatalog 备注:加粗部分为个人思考 程序员用自己的技术变现是天经地义的事情。写程序是一门手艺活,程序员作为手艺人完全可以不依赖任何公司或者其他…...

Typora结合PicGo + Github搭建个人图床
目录 一 、GitHub仓库设置 1、新建仓库 2、创建Token 并复制保存 二、PicGo客户端配置 1、下载 & 安装 2、配置图床 三、Typora配置 一 、GitHub仓库设置 1、新建仓库 点击主页右上角的 号创建 New repository 填写仓库信息 2、创建Token 并复制保存 点击右上角…...

【JavaWeb】Day27.Web入门——Tomcat介绍
目录 WEB服务器-Tomcat 一.服务器概述 二.Web服务器 三.Tomcat- 基本使用 1.下载 2.安装与卸载 3.启动与关闭 4.常见问题 四.Tomcat- 入门程序 WEB服务器-Tomcat 一.服务器概述 服务器硬件:指的也是计算机,只不过服务器要比我们日常使用的计算…...

怎么更新sd-webui AUTOMATIC1111/stable-diffusion-webui ?
整个工程依靠脚本起来的: 可直接到stable-diffusion-webui子目录执行: git pull更新代码完毕后,删除venv的虚拟环境。 然后再次执行webui.sh,这样会自动重新启动stable-diffusion-webui....
Apache Iceberg最新最全面试题及详细参考答案(持续更新)
目录 1. 描述Apache Iceberg的架构设计和它的主要组件? 2. Iceberg如何处理数据的版本控制和时间旅行?...

从TCP/IP协议到socket编程详解
我的所有学习笔记:https://github.com/Dusongg/StudyNotes⭐⭐⭐ 文章目录 1 网络基础知识1.1 查看网络信息1.2 认识端口号1.3 UDP1.4 TCP1.4.1 确认应答机制1.4.2 TCP三次握手/四次挥手为什么是三次握手为什么是四次挥手listen 的第二个参数 backlog—— 全…...

uniapp开发小程序遇到的问题,持续更新中
一、uniapp引入全局scss 在App.vue中引入uni.scss <style lang"scss">/* #ifndef APP-NVUE */import "uni.scss";/* #endif */ </style>注意:nvue页面的样式在编译时,有很多样式写法被限制了,容易报错。所…...
C++经典面试题目(十一)
1. final和override关键字 在C中,final 和 override 是两个用于类继承和成员函数重写的关键字,它们主要在面向对象编程的上下文中使用,以增强代码的可读性和安全性。 1. final 关键字 final 关键字主要有两种用法: 用于类&…...
设计模式(6):桥接模式
一.桥接模式核心要点 处理多层继承结构,处理多维度变化的场景,将各个维度设计成独立的继承结构,使各个维度可以独立的扩展在抽象层建立关系。 \color{red}{处理多层继承结构,处理多维度变化的场景,将各个维度设计成独立…...
Java切面编程
1.切面编程 无需改变原有类的情况下对业务功能实现扩展或增强。 2.目前最流行的AOP框架有两个,分别为Spring AOP 和 AspectJ。 3.Spring AOP使用纯java实现,不需要专门的编译过程和类加载器,在运行期间通过代理方式向目标类织入增强的代码。 …...

微服务demo(二)nacos服务注册与集中配置
环境:nacos1.3.0 一、服务注册 1、pom: 移步spring官网https://spring.io,查看集成Nacos所需依赖 找到对应版本点击进入查看集成说明 然后再里面找到集成配置样例,这里只截一张,其他集成内容继续向下找 我的&#x…...
面试题库二
1、简述TCP/IP的三次握手和四次挥手 TCP(Transmission Control Protocol)是一种可靠的、面向连接的传输层协议,用于在网络中传输数据。在建立连接和断开连接时,TCP 使用了三次握手和四次挥手来确保通信的可靠性和正确性。 三次握手…...

HarmonyOS实战开发-如何实现一个简单的电子相册应用开发
介绍 本篇Codelab介绍了如何实现一个简单的电子相册应用的开发,主要功能包括: 实现首页顶部的轮播效果。实现页面跳转时共享元素的转场动画效果。实现通过手势控制图片的放大、缩小、左右滑动查看细节等效果。 相关概念 Swiper:滑块视图容…...

FFmpeg将绿幕视频处理成透明视频播放
怎么在网页端插入透明视频呢,之前在做Web3D项目时,使用threejs可以使绿幕视频透明显示在三维场景中,但是在网页端怎么让绿幕视频透明显示呢? 如图上图,视频背景遮挡住后面网页内容 想要如下图效果 之前有使用过ffmpeg…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...

无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...