设计模式(21)中介者模式
一、介绍:
1、定义:中介者模式(Mediator Pattern)是一种行为型设计模式,它通过引入一个中介者对象来降低多个对象之间的耦合度。在中介者模式中,各个对象之间不直接进行通信,而是通过中介者对象进行协调和通信。
2、组成结构:
(1)抽象中介者(Abstract Mediator):定义了中介者对象的接口,用于协调各个同事对象之间的交互。
(2)具体中介者(Concrete Mediator):实现了抽象中介者接口,负责协调各个同事对象的交互,并了解各个同事对象的具体实现。
(3)抽象同事类(Abstract Colleague):定义了同事对象的接口,通常持有一个中介者对象的引用,用于与中介者进行通信。
(4)具体同事类(Concrete Colleague):实现了抽象同事类的接口,实现自身的业务逻辑,并通过中介者对象进行与其他同事对象的通信。
// 抽象中介者
interface Mediator {void send(String message, Colleague colleague);
}// 具体中介者
class ConcreteMediator implements Mediator {private Colleague colleague1;private Colleague colleague2;public void setColleague1(Colleague colleague1) {this.colleague1 = colleague1;}public void setColleague2(Colleague colleague2) {this.colleague2 = colleague2;}@Overridepublic void send(String message, Colleague colleague) {if (colleague == colleague1) {colleague2.receive(message);} else {colleague1.receive(message);}}
}// 抽象同事类
abstract class Colleague {protected Mediator mediator;public Colleague(Mediator mediator) {this.mediator = mediator;}public abstract void send(String message);public abstract void receive(String message);
}// 具体同事类
class ConcreteColleague1 extends Colleague {public ConcreteColleague1(Mediator mediator) {super(mediator);}@Overridepublic void send(String message) {mediator.send(message, this);}@Overridepublic void receive(String message) {System.out.println("ConcreteColleague1 Received: " + message);}
}class ConcreteColleague2 extends Colleague {public ConcreteColleague2(Mediator mediator) {super(mediator);}@Overridepublic void send(String message) {mediator.send(message, this);}@Overridepublic void receive(String message) {System.out.println("ConcreteColleague2 Received: " + message);}
}// 客户端
public static void main(String[] args) {ConcreteMediator mediator = new ConcreteMediator();ConcreteColleague1 colleague1 = new ConcreteColleague1(mediator);ConcreteColleague2 colleague2 = new ConcreteColleague2(mediator);mediator.setColleague1(colleague1);mediator.setColleague2(colleague2);colleague1.send("msg from Colleague1");colleague2.send("msg from Colleague2");}
3、优点:
(1)降低耦合度:中介者模式将对象之间的交互集中在中介者对象中,减少了对象之间的直接依赖和耦合度,使系统更加灵活、可扩展和易于维护。
(2)简化对象间的通信:中介者模式通过引入中介者对象,将对象间复杂的相互通信转变为对象与中介者之间的简单交互,简化了对象间的通信逻辑。
(3)集中控制逻辑:中介者模式将对象间的交互逻辑集中在中介者对象中,使得系统的控制逻辑更加清晰明确。通过定义中介者对象来协调对象间的交互,可以更方便地修改和扩展系统的行为。
(4)促进代码重用:中介者模式将公共的交互逻辑封装在中介者对象中,可以被多个对象共享和复用,避免了代码的重复编写,提高了代码的可维护性和可复用性。
4、适用场景:
(1)当一个系统中对象之间存在复杂的相互关系,导致对象间的交互逻辑难以维护和扩展时,可以考虑使用中介者模式来简化交互逻辑。
(2)当一个对象需要对多个对象进行操作或通知时,可以引入中介者模式来集中管理这些对象之间的交互。
(3)当系统中的对象之间存在循环依赖关系,不方便直接进行交互时,可以通过引入中介者对象来解决循环依赖问题。
二、demo:
1、房租中介:三个房东、三个租客。房东类和租客类互相影响,称为同事类。
(1)抽象同事类
import java.util.Objects;/*** 抽象同事类(这里指房东、租客),有用户名称,以及消息发送、接收功能*/
public abstract class Colleague {//租客、房东 都认识中介Mediator mediator;public String userName;public Colleague(String userName, Mediator mediator){this.userName = userName;this.mediator = mediator;}//这里对userName做equals和hashCode,是为了后面可以用contains判断方法@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Colleague colleague = (Colleague) o;return Objects.equals(userName, colleague.userName);}@Overridepublic int hashCode() {return Objects.hash(userName);}public void sendMsg(String msg){System.out.println("我"+this.userName+"发送消息");}public void receiveMsg(String msg,Colleague fromColleague){}
}
(2)具体同事类,房东和租客
//房东类
public class LandlordColleague extends Colleague{public LandlordColleague(String userName, Mediator mediator) {super(userName,mediator);}//发送消息,需要通知谁 谁可以收到由中介完成@Overridepublic void sendMsg(String msg) {super.sendMsg(msg);mediator.notice(msg,this);}//收到中介发送的消息@Overridepublic void receiveMsg(String msg,Colleague fromColleague) {System.out.println("房东"+this.userName+"收到"+fromColleague.userName+"发送的消息"+msg);}
}
import java.util.List;//租客同事类
public class TenantColleague extends Colleague {public TenantColleague(String userName, Mediator mediator) {super(userName,mediator);}//发送消息,谁可以收到(所有房东)由中介完成@Overridepublic void sendMsg(String msg) {super.sendMsg(msg);mediator.notice(msg,this);}//收到消息@Overridepublic void receiveMsg(String msg,Colleague fromColleague) {System.out.println("租客"+this.userName+"收到"+fromColleague.userName+"发送的消息"+msg);}
}
(3)抽象中介
//抽象中介
public interface Mediator {//通知void notice(String msg,Colleague fromColleague);
}
(4)具体中介
import java.util.ArrayList;
import java.util.List;/*** 房租中介*/
public class RentMediator implements Mediator{//所有租客List<Colleague> tenantColleagues = new ArrayList<>();//所有房东List<Colleague> landlordColleagues = new ArrayList<>();//添加房东void addLandlord(Colleague colleague){this.landlordColleagues.add(colleague);}//添加租客void addTenantColleague(Colleague colleague){this.tenantColleagues.add(colleague);}/*** 通知* 通知所有房东or 租客* @param msg* @param fromColleague*/@Overridepublic void notice(String msg, Colleague fromColleague) {//房东发的,通知所有租客if(landlordColleagues.contains(fromColleague)){for(Colleague colleague : tenantColleagues){colleague.receiveMsg(msg,fromColleague);}}//租客发的,通知所有房东if(tenantColleagues.contains(fromColleague)){for(Colleague colleague : landlordColleagues){colleague.receiveMsg(msg,fromColleague);}}}
}
客户端:
public class Test {public static void main(String args[]){RentMediator rentMediator = new RentMediator();//房东管理LandlordColleague landlordColleague1 = new LandlordColleague("房东1",rentMediator);LandlordColleague landlordColleague2 = new LandlordColleague("房东2",rentMediator);LandlordColleague landlordColleague3 = new LandlordColleague("房东3",rentMediator);rentMediator.addLandlord(landlordColleague1);rentMediator.addLandlord(landlordColleague2);rentMediator.addLandlord(landlordColleague3);//租客管理TenantColleague tenantColleague1 = new TenantColleague("租客1",rentMediator);TenantColleague tenantColleague2 = new TenantColleague("租客2",rentMediator);TenantColleague tenantColleague3 = new TenantColleague("租客3",rentMediator);rentMediator.addTenantColleague(tenantColleague1);rentMediator.addTenantColleague(tenantColleague2);rentMediator.addTenantColleague(tenantColleague3);//tenantColleague2.sendMsg("寻找三室房源");System.out.println("******");landlordColleague3.sendMsg("发布新房源");}
}输出:
我租客2发送消息
房东房东1收到租客2发送的消息寻找三室房源
房东房东2收到租客2发送的消息寻找三室房源
房东房东3收到租客2发送的消息寻找三室房源
******
我房东3发送消息
租客租客1收到房东3发送的消息发布新房源
租客租客2收到房东3发送的消息发布新房源
租客租客3收到房东3发送的消息发布新房源
相关文章:

设计模式(21)中介者模式
一、介绍: 1、定义:中介者模式(Mediator Pattern)是一种行为型设计模式,它通过引入一个中介者对象来降低多个对象之间的耦合度。在中介者模式中,各个对象之间不直接进行通信,而是通过中介者对象…...

JVM虚拟机:通过一个例子解释JVM中栈结构的使用
代码 代码解析 main方法执行,创建栈帧并压栈。 int d8,d为局部变量,是基础类型,它位于虚拟机栈的局部变量表中 然后创建了一个TestDemo的对象,这个对象在堆中,并且这个对象的成员变量(day&am…...

会自动写代码的AI大模型来了!阿里云推出智能编码助手通义灵码
用大模型写代码是什么样的体验?10月31日,杭州云栖大会上,阿里云对外展示了一款可自动编写代码的 AI 助手,在编码软件的对话窗口输入“帮我用 python 写一个飞机游戏”,短短几秒,这款名为“通义灵码”的 AI …...

如何公网远程访问本地WebSocket服务端
本地websocket服务端暴露至公网访问【cpolar内网穿透】 文章目录 本地websocket服务端暴露至公网访问【cpolar内网穿透】1. Java 服务端demo环境2. 在pom文件引入第三包封装的netty框架maven坐标3. 创建服务端,以接口模式调用,方便外部调用4. 启动服务,出现以下信息表示启动成功…...

python 练习 在列表元素中合适的位置插入 输入值
目的: 有一列从小到大排好的数字元素列表, 现在想往其插入一个值,要求: 大于右边数字小于左边数字 列表元素: [1,4,6,13,16,19,28,40,100] # 方法: 往列表中添加一个数值,其目的方便元素位置往后…...

企业级JAVA、数据库等编程规范之命名风格 —— 超详细准确无误
🧸欢迎来到dream_ready的博客,📜相信你对这两篇博客也感兴趣o (ˉ▽ˉ;) 📜 表白墙/留言墙 —— 初级SpringBoot项目,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学 📜 用户登录前后端…...

有什么可以自动保存微信收到的图片和视频的方法么
8-1 在一些有外勤工作的公司里,经常会需要在外面工作的同事把工作情况的图片发到指定微信或者指定的微信群里,以记录工作进展等,或者打卡等,对于外勤人员来说,也就发个图片的事,但是对于在公司里收图片的人…...

面试算法46:二叉树的右侧视图
题目 给定一棵二叉树,如果站在该二叉树的右侧,那么从上到下看到的节点构成二叉树的右侧视图。例如,图7.6中二叉树的右侧视图包含节点8、节点10和节点7。请写一个函数返回二叉树的右侧视图节点的值。 分析 既然这个题目和二叉树的层相关&a…...

R语言使用surveyCV包对NHANES数据(复杂调查加权数据)进行10折交叉验证
美国国家健康与营养调查( NHANES, National Health and Nutrition Examination Survey)是一项基于人群的横断面调查,旨在收集有关美国家庭人口健康和营养的信息。 地址为:https://wwwn.cdc.gov/nchs/nhanes/Default.aspx 既往咱们…...

WOS与CNKI数据库的citespace分析教程及常见问题解决
本教程为面向新手的基于citespace的数据可视化教程,旨在帮助大家更快了解行业前沿的研究内容。 获取最新版本的citespace软件 在citespace官网下载最新的版本(如果是老版本,可能会提示让你去官网更新为最新版,老版本不再提供服务…...

NEFU数字图像处理(三)图像分割
一、图像分割的基本概念 1.1专有名词 前景和背景 在图像分割中,我们通常需要将图像分为前景和背景两个部分。前景是指图像中我们感兴趣、要分割出来的部分,背景是指和前景不相关的部分。例如,对于一张人物照片,人物就是前景&…...

UEditorPlus v3.6.0 图标补全,精简代码,快捷操作重构,问题修复
UEditor是由百度开发的所见即所得的开源富文本编辑器,基于MIT开源协议,该富文本编辑器帮助不少网站开发者解决富文本编辑器的难点。 UEditorPlus 是有 ModStart 团队基于 UEditor 二次开发的富文本编辑器,主要做了样式的定制,更符…...

C++ Set
定义 set不同于vector,strin,list这种存储容器,set是一种关联式容器,底层是搜二叉; 功能 set可以确定唯一的值,可以排序去重。 接口 insert() #include <iostream> #include<set> using namespace std;int main…...

基于知识库的chatbot或者FAQ
背景 最近突然想做一个基于自己的知识库(knowlegebase)的chatbot或者FAQ的项目。未来如果可以在公司用chatgpt或者gpt3.5之后的模型的话,还可以利用gpt强大的语言理解力和搜索出来的用户问题的相关业务文档来回答用户在业务中的问题。 Chat…...

ZOC8 for Mac:超越期待的终端仿真器
在Mac上,一个优秀的终端仿真器是每位开发者和系统管理员的必备工具。ZOC8,作为一款广受好评的终端仿真器,以其强大的功能和易用性,已经在Mac用户中积累了良好的口碑。本文将为您详细介绍ZOC8的各项特性,以及为什么它会…...
织梦dedecms后台档案列表显示空白或显示不了文章的解决方法
织梦dedecms后台档案列表显示空白或显示不了文章的解决方法 dede/content_list.php空白解决方法如下 dede/content_list.php空白 在DEDE后台可以查看栏目文章,但是所有档案列表却为空白或者显示不了文章,如图所示: 后来找到dede/content_list.php,看了下…...

10本值得阅读的量化交易书籍
什么是量化交易? 量化交易是利用数学模型或算法来创建交易策略并进行交易。量化交易通常由大型机构交易员或对冲基金雇用,他们雇用大量的博士和工程师团队。从历史上看,量化交易领域一直非常隐秘,有效的想法往往受到公司的严密保…...
c++通过对象的地址初始化指针,需要对指针进行释放么(企业链表衍生)
在C中,如果你通过对象的地址来初始化指针,通常情况下是不需要手动释放指针的。这是因为对象的生存期与指针所指向的对象的生存期相关联。当对象超出其作用域或被销毁时,指向该对象的指针也会自动成为悬挂指针,这种情况下再访问该指…...
CentOS安装MySQL
参考官方链接:https://dev.mysql.com/doc/refman/8.0/en/linux-installation-rpm.html CentOS版本 [rootlocalhost ~]# cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core) 下载MySQL安装包(版本:8.0.35) 访问地址…...

19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...

华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
2023赣州旅游投资集团
单选题 1.“不登高山,不知天之高也;不临深溪,不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...

Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...