Java中介者模式
目录
定义
结构
案例
优点
缺点
使用场景
定义
又叫调停模式,定义一个中介角色来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。
结构
中介者模式包含以下主要角色:
- 抽象中介者角色:它是中介者的接口,提供了同事对象注册与转发同事对象信息的抽象方法。
- 具体中介者角色:实现中介者接口,定义一个 List 来管理同事对象,协调各个同事角色之间的交互关系,因此它依赖于同事角色。
- 抽象同事类角色:定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。
- 具体同事类角色:是抽象同事类的实现者,当需要与其他同事对象交互时,由中介者对象负责后续的交互。
案例
//抽象中介类
public abstract class Mediator {public abstract void contact(String message,Person person);public abstract void getMessage(Person person);
}
具体中介类
public class MediatorStructure extends Mediator {private List<HouseOwner> houseOwners = new ArrayList<>();private List<Tenant> tenants = new ArrayList<>();//购房者的要求private Map<Tenant, List<String>> tenantRequest = new HashMap<>();//房主的服务private Map<HouseOwner, List<String>> houseOwnerResponse = new HashMap<>();public List<HouseOwner> getHouseOwners() {return houseOwners;}public void setHouseOwners(HouseOwner houseOwner) {houseOwners.add(houseOwner);}public List<Tenant> getTenants() {return tenants;}public void setTenants(Tenant tenant) {tenants.add(tenant);}@Overridepublic void contact(String message, Person person) {List<String> list = null;if (person instanceof HouseOwner) {//说明是房主联系中介,中介需要把消息给对应的购房者//首先判断信息map中有没有这个房主信息HouseOwner houseOwner = (HouseOwner) person;list = houseOwnerResponse.get(person);if (list == null || list.size() <= 0) {//说明没有这个房主的信息list = new ArrayList<>();list.add(message);houseOwnerResponse.put(houseOwner, list);} else {if (list.contains(message)) {//说明已经存在这个消息了return;}list.add(message);houseOwnerResponse.put(houseOwner, list);}} else {//说明购房者发起了消息Tenant tenant = (Tenant) person;list = tenantRequest.get(tenant);if (list == null || list.size() <= 0) {list = new ArrayList<>();//说明没有这个购房者的信息list.add(message);tenantRequest.put(tenant, list);} else {if (list.contains(message)) {//说明已经存在这个消息了return;}list.add(message);tenantRequest.put(tenant, list);}}}public void getMessage(Person person) {Set<String> set = new HashSet<>();if (person instanceof HouseOwner) {//房主主动获取购房者的需求for (Tenant tenant : tenantRequest.keySet()) {List<String> list = tenantRequest.get(tenant);set.addAll(list);}((HouseOwner) person).getMessage(set);} else {//购房者只需要知道符合自己的就可以List<String> list = tenantRequest.get(person);for (String s : list) {for (HouseOwner houseOwner : houseOwnerResponse.keySet()) {List<String> response = houseOwnerResponse.get(houseOwner);if (response.contains(s)) {set.add(houseOwner.name);}}}((Tenant) person).getMessage(set);}}
}
抽象同事类
public abstract class Person {protected String name;protected Mediator mediator;public String getName() {return name;}public void setName(String name) {this.name = name;}public Mediator getMediator() {return mediator;}public void setMediator(Mediator mediator) {this.mediator = mediator;}public Person(String name, Mediator mediator) {this.name = name;this.mediator = mediator;}abstract void contact(String message);
}
房主
public class HouseOwner extends Person {public HouseOwner(String name, Mediator mediator) {super(name, mediator);}@Overridevoid contact(String message) {System.out.println(name+"房主发布了一条消息:"+message);mediator.contact(message,this);}public void getMessage(Set message){System.out.println(name+"房主获得了消息:"+message);}
}public class Tenant extends Person{public Tenant(String name, Mediator mediator) {super(name, mediator);}@Overridevoid contact(String message) {System.out.println(name+"购房者发布了一条消息:"+message);mediator.contact(message,this);}void getMessage(Set message){System.out.println(name+"购房者获得了消息:"+message);}
}
测试
public class Client {public static void main(String[] args) {MediatorStructure mediatorStructure = new MediatorStructure();HouseOwner houseOwnerOne = new HouseOwner("房主一号", mediatorStructure);HouseOwner houseOwnerTwo = new HouseOwner("房主二号", mediatorStructure);Tenant tenantOne = new Tenant("买房一号",mediatorStructure);Tenant tenantTwo = new Tenant("买房一号",mediatorStructure);mediatorStructure.setHouseOwners(houseOwnerOne);mediatorStructure.setHouseOwners(houseOwnerTwo);mediatorStructure.setTenants(tenantOne);mediatorStructure.setTenants(tenantTwo);tenantOne.contact("汤臣一品");tenantOne.contact("汤臣二品");tenantTwo.contact("汤臣三品");tenantTwo.contact("汤臣四品");houseOwnerOne.contact("汤臣一品");houseOwnerTwo.contact("汤臣六品");mediatorStructure.getMessage(houseOwnerOne);mediatorStructure.getMessage(tenantOne);}
}
买房一号购房者发布了一条消息:汤臣一品
买房一号购房者发布了一条消息:汤臣二品
买房一号购房者发布了一条消息:汤臣三品
买房一号购房者发布了一条消息:汤臣四品
房主一号房主发布了一条消息:汤臣一品
房主二号房主发布了一条消息:汤臣六品
房主一号房主获得了消息:[汤臣三品, 汤臣四品, 汤臣二品, 汤臣一品]
买房一号购房者获得了消息:[房主一号]
案例中存在两种同事角色,购房者以及房主,中介类保存不同同事类对象,然后根据不同同事类给出不同返回结果。
优点
- 松散耦合中介者模式通过把多个同事对象之间的交互封装到中介者对象里面,从而使得同事对象之间松散耦合,基本上可以做到互补依赖。这样一来,同事对象就可以独立地变化和复用,而不再像以前那样“牵一处而动全身”了。
- 集中控制交互多个同事对象的交互,被封装在中介者对象里面集中管理,使得这些交互行为发生变化的时候,只需要修改中介者对象就可以了,当然如果是已经做好的系统,那么就扩展中介者对象,而各个同事类不需要做修改。
- 一对多关联转变为一对一的关联没有使用中介者模式的时候,同事对象之间的关系通常是一对多的,引入中介者对象以后,中介者对象和同事对象的关系通常变成双向的一对一,这会让对象的关系更容易理解和实现。
缺点
当同事类太多时,中介者的职责将很大,它会变得复杂而庞大,以至于系统难以维护。
使用场景
- 系统中对象之间存在复杂的引用关系,系统结构混乱且难以理解。
- 当想创建一个运行于多个类之间的对象,又不想生成新的子类时。
相关文章:
Java中介者模式
目录 定义 结构 案例 优点 缺点 使用场景 定义 又叫调停模式,定义一个中介角色来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。 结构 中介者模式包含以下主要角色: 抽象中介者角…...
前端框架Vue学习 ——(五)前端工程化Vue-cli脚手架
文章目录 Vue-cliVue项目-创建Vue项目-目录结构Vue项目-启动Vue项目-配置端口Vue项目开发流程 Vue-cli 介绍:Vue-cli 是 Vue 官方提供的一个脚手架,用于快速生成一个 Vue 的项目模版 安装 NodeJS安装 Vue-cli npm install -g vue/cliVue项目-创建 图…...
App备案-iOS云管理式证书 Distribution Managed 公钥及证书SHA-1指纹的获取方法
根据近日工业和信息化部发布的《工业和信息化部关于开展移动互联网应用程序备案工作的通知》,相信不少要进行IOS平台App备案的朋友遇到了一个问题,就是apple不提供云管理式证书的下载,也就无法获取公钥及证书SHA-1指纹。 已经上架的应用不想重…...
Spring -Spring之依赖注入源码解析
依赖注入底层原理流程图:Spring中Bean的依赖注入原理| ProcessOn免费在线作图,在线流程图,在线思维导图 Spring中到底有几种依赖注入的方式? 首先分两种: 手动注入自动注入 手动注入 在XML中定义Bean时,就是手动注入…...
Spire.Office for .NET 8.10.2 同步更新-Crk
Spire.Office for .NET是 E-iceblue 提供的企业级 Office .NET API 的组合。它包括Spire.Doc、Spire.XLS、Spire.Spreadsheet、Spire.Presentation、Spire.PDF、Spire.DataExport、Spire.OfficeViewer、Spire.PDFViewer、Spire.DocViewer、Spire.Barcode和Spire.Email。Spire.O…...
MFC 基础篇(一)
目录 一.SDK编程 二.为什么要学MFC? 三.MFC能做什么? 四.MFC开发环境搭建 五.MFC项目创建 六.消息映射机制 一.SDK编程 Application Programming Interface 应用程序编程接口。 Software Development Kit 软件开发工具包,一般会包括A…...
Android技术-修改SO导出符号
背景 经常在使用第三方SDK的时候会莫名其妙报错,其中最常见的一种就是SO符号冲突,比如libA.so静态链接了libC.a,而libB.so动态链接了libC.so。这样便会导致符号冲突。又或者在使用不同版本的动态库,也会造成符号冲突。 报错案例 案例1 DEB…...
flutter 打包apk
Flutter项目打包生成APK_flutter打包apk_文阿花的博客-CSDN博客 关于iconData可能出现的错误: flutter build apk 打包报错调试过程 - 掘金 (juejin.cn) 使用命令行:flutter build apk --no-tree-shake-icons...
Halcon如何使用SaperaLT库连接dalsa相机
halcon安装好的时候,没有带SaperaLT的采集库,需要额外在Halcon官网下载此库。 以下是halcon官网下载此库的链接。官网需要注册才可以下载。 https://www.mvtec.com/downloads/interfaces?tx_mvtecproduct_extensiondownloadlist%5Bfilter%5D%5B0%5Dma…...
Vue 嵌套路由 多级路由规则
套娃路由 routes:[{path: /login,component: Login},{path: /user,component: User,children:[{ path: test, component: Test },{ path: test2, component: Test2 },]}]子路由不需要加/ 在父组件 子路由不需要加/ 需要带上父亲的路由路径 <router-link to"user/test…...
pandas教程:Introduction to pandas Data Structures pandas的数据结构
文章目录 Chapter 5 Getting Started with pandas5.1 Introduction to pandas Data Structures1 Series2 DataFrame3 Index Objects (索引对象) Chapter 5 Getting Started with pandas 这样导入pandas: import pandas as pde:\python3.7\lib\site-packages\numpy…...
MinIO 分布式文件(对象)存储
简介 MinIO是高性能、可扩展、云原生支持、操作简单、开源的分布式对象存储产品。 在中国:阿里巴巴、腾讯、百度、中国联通、华为、中国移动等等9000多家企业也都在使用MinIO产品 官网地址:http://www.minio.org.cn/ 下载 官网下载(8.4.3版本)&#x…...
HTML表单标签
## HTML标签:表单标签 * 表单: * 概念:用于采集用户输入的数据的。用于和服务器进行交互。 * form:用于定义表单的。可以定义一个范围,范围代表采集用户数据的范围 * 属性࿱…...
【黑马程序员】SpringCloud——Eureka
文章目录 前言一、提供者与消费者1. 服务调用关系 二、远程调用的问题三、eureka 原理分析1. eureka 的作用 四、Eureka 案例1. 搭建 eureka 服务1. 服务注册1.1 注册 user-service1.2 启动 user-service3. order-service 完成服务注册 3. 服务发现1. 在 order-service 完成服务…...
目标跟踪(DeepSORT)
本文首先将介绍在目标跟踪任务中常用的匈牙利算法(Hungarian Algorithm)和卡尔曼滤波(Kalman Filter),然后介绍经典算法DeepSORT的工作流程以及对相关源码进行解析。 目前主流的目标跟踪算法都是基于Tracking-by-Detec…...
2 任务2: 使用趋动云GPU进行猫狗识别实践
使用趋动云GPU进行猫狗识别实践 1 创建项目2 初始化开发环境3 调试代码4 提交离线任务5 结果集存储与下载 使用趋动云提供的免费GPU,进行猫狗识别实践。 虽然例程里面提供的是基于tensorflow的,但是你也可以使用pytorch的代码 使用这个平台的一个优点就是…...
技术分享 | app自动化测试(Android)--显式等待机制
WebDriverWait类解析 WebDriverWait 用法代码 Python 版本 WebDriverWait( driver,timeout,poll_frequency0.5,ignored_exceptionsNone) 参数解析: driver:WebDriver 实例对象 timeout: 最长等待时间,单位秒 poll_frequency: 检测的间…...
机器学习基础之《回归与聚类算法(5)—分类的评估方法》
问题:上一篇的案例,真的患癌症的,能被检查出来的概率? 一、精确率和召回率 1、混淆矩阵 在分类任务下,预测结果(Predicted Condition)与正确标记(True Condition)之间存在四种不同的组合,构成混淆矩阵(适…...
如何在macbook上删除文件?Mac删除文件的多种方法
在使用MacBook电脑时,桌面上经常会积累大量的文件,而这些文件可能已经不再需要或已经过时。为了保持桌面的整洁和提高电脑性能,我们需要及时删除这些文件。本文将介绍MacBook怎么删除桌面文件,以及macbook删除桌面文件快捷键。 一…...
Java代码Demo——Map根据key或value排序
Map根据key排序 升序 Demo代码: //使用TreeMap Map<Integer, String> map new TreeMap<>(); map.put(10, "第10名次"); map.put(15, "第15名次"); map.put(1, "第1名次"); map.put(5, "第5名次"); map.put…...
(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
中医有效性探讨
文章目录 西医是如何发展到以生物化学为药理基础的现代医学?传统医学奠基期(远古 - 17 世纪)近代医学转型期(17 世纪 - 19 世纪末)现代医学成熟期(20世纪至今) 中医的源远流长和一脉相承远古至…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...
关于uniapp展示PDF的解决方案
在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项: 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库: npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...
Python网页自动化Selenium中文文档
1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API,让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API,你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...
【FTP】ftp文件传输会丢包吗?批量几百个文件传输,有一些文件没有传输完整,如何解决?
FTP(File Transfer Protocol)本身是一个基于 TCP 的协议,理论上不会丢包。但 FTP 文件传输过程中仍可能出现文件不完整、丢失或损坏的情况,主要原因包括: ✅ 一、FTP传输可能“丢包”或文件不完整的原因 原因描述网络…...
