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);}
}

买房一号购房者发布了一条消息:汤臣一品

买房一号购房者发布了一条消息:汤臣二品

买房一号购房者发布了一条消息:汤臣三品

买房一号购房者发布了一条消息:汤臣四品

房主一号房主发布了一条消息:汤臣一品

房主二号房主发布了一条消息:汤臣六品

房主一号房主获得了消息:[汤臣三品, 汤臣四品, 汤臣二品, 汤臣一品]

买房一号购房者获得了消息:[房主一号]

案例中存在两种同事角色,购房者以及房主,中介类保存不同同事类对象,然后根据不同同事类给出不同返回结果。

优点

  • 松散耦合中介者模式通过把多个同事对象之间的交互封装到中介者对象里面,从而使得同事对象之间松散耦合,基本上可以做到互补依赖。这样一来,同事对象就可以独立地变化和复用,而不再像以前那样“牵一处而动全身”了。
  • 集中控制交互多个同事对象的交互,被封装在中介者对象里面集中管理,使得这些交互行为发生变化的时候,只需要修改中介者对象就可以了,当然如果是已经做好的系统,那么就扩展中介者对象,而各个同事类不需要做修改。
  • 一对多关联转变为一对一的关联没有使用中介者模式的时候,同事对象之间的关系通常是一对多的,引入中介者对象以后,中介者对象和同事对象的关系通常变成双向的一对一,这会让对象的关系更容易理解和实现。

缺点

当同事类太多时,中介者的职责将很大,它会变得复杂而庞大,以至于系统难以维护。

使用场景

  • 系统中对象之间存在复杂的引用关系,系统结构混乱且难以理解。
  • 当想创建一个运行于多个类之间的对象,又不想生成新的子类时。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/132948.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【LVS实战】03 LVS负载均衡-DR模式实验

本文介绍&#xff0c;如何通过ipvsadm配置负载均衡&#xff0c;并且转发模式为DR直接路由模式 一、网络拓扑 如下图&#xff1a; LVS负载均衡的机器&#xff0c;配置了一个VIP&#xff1a;10.1.0.7 二、前置准备 每台机器关闭防火墙 systemctl stop firewalldRS装好ngin…

如何用 GPT-4 全模式(All Tools)帮你高效学习和工作?

「十项全能」的 ChatGPT &#xff0c;用起来感受如何&#xff1f; 之前&#xff0c;作为 ChatGPT Plus 用户&#xff0c;如果你集齐下面这五个模式&#xff0c;就会成为别人羡慕的对象。 但现在&#xff0c;人们更加期盼的&#xff0c;是下面这个提示的出现&#xff1a; 这个提…

ZZ038 物联网应用与服务赛题第I套

2023年全国职业院校技能大赛 中职组 物联网应用与服务 任 务 书 &#xff08;I卷&#xff09; 赛位号&#xff1a;______________ 竞赛须知 一、注意事项 1.检查硬件设备、电脑设备是否正常。检查竞赛所需的各项设备、软件和竞赛材料等; 2.竞赛任务中所使用的各类软件工…

http中的Content-Type类型

浏览器的Content-Type 最近在做web端下载的时候需要给前端返回一个二进制的流&#xff0c;需要在请求头中设置一个 writer.Header().Set("Content-Type", "application/octet-stream")那么http中的Content-Type有具体有哪些呢&#xff1f;他们具体的使用场…

超详细的wheel轮子下载和.whl安装

wheel安装 pip安装失败问题 基于Anaconda进行 pip install ,报如下 但基于此路径下安装.whl文件时候&#xff0c;会报如下 通过在可借鉴的博客上查找相关原因&#xff0c;发现原来是因为版本没有匹配的问题&#xff0c;基于此问题以及博客中的解决方案&#xff0c;进行亲测…

Pandas练手项目

一、chipotle tsv 数据集&#xff1a;chipotle.tsv-数据集 代码&#xff1a;https://download.csdn.net/download/Albert233333/88508819 1 导入数据 # order_id这一列相同的数字表示 一个消费者同一次进行的交易 # 表格中的每一行表示 用户一次购买的某一个品类 购买的数量…

1、Sentinel基本应用限流规则(1)

Sentinel基本应用&限流规则 1.1 概述与作用 随着微服务的流行&#xff0c;服务和服务之间的稳定性变得越来越重要。缓存、降级和限流是保护微服务系统运行稳定性的三大利器。 缓存&#xff1a;提升系统访问速度和增大系统能处理的容量 降级&#xff1a;当服务出问题或者影…

12 款小众宝藏AI工具,90% 的开发者不了解

AI工具的发展一日千里&#xff0c;了解这些AI工具的功能以及它们如何提高开发过程中的效率和创新&#xff0c;变得尤为重要&#xff0c;这里分享了 12个宝藏的人工智能和低代码工具&#xff0c;希望对大家的工作与学习有所帮助。 1.Pieces for Developers 网址&#xff1a;ht…

Technology Strategy Pattern 学习笔记5 -Creating the Strategy-Department Context

Creating the Strategy-Department Context 1 situations This pattern helps you organize your thoughts, and consider the department holistically in the following situations 1.1 •Aligning teams around a vision, especially a new direction 1.2 •Setting up a …

presto插件机制揭秘:探索无限可能的数据处理舞台

文章目录 1. 前言2. Presto插件架构3. Plugin接口3.1 插件协议3.2 插件实现类 4. 插件加载过程4.1 PluginManager 5. 插件应用6. 总结 关键词&#xff1a;Presto Plugin 1. 前言 本文源码环境&#xff1a; presto: prestoDb 0.275版本 在Presto框架中插件机制设计是一种非常常见…

lombok依赖介绍(帮助我们消除冗长代码,如get,set方法)

前言 lombok 是一个 Java 工具库&#xff0c;通过注解的方式&#xff0c;简化 Java 开发。要想使用 lombok 中的注解&#xff0c;我们需要先引入依赖&#xff0c;推荐看idea必装插件EditStarters&#xff08;快速引入依赖&#xff09;&#xff0c;lombok是⼀款在编译期⽣成代码…

随身wifi编译Openwrt的ImmortalWrt分支

背景&#xff1a; 之前用酷安上下载的苏苏亮亮版友提供的Openwrt&#xff0c;在高通410棒子上刷机成功&#xff0c;但编译一直就没搞定。近期听说又出了个分支版本ImmortalWrt&#xff0c;刷了个版本&#xff0c;感觉界面清爽不少&#xff0c;内核也升级&#xff0c;遂打算搞定…

python面向对象编程:魔方法和内置属性

__init__(self)是初始化方法&#xff0c;初始化实例的时候自动调用&#xff0c;方法有一个参数 self&#xff0c;代表当前创建的实例对象。__init__方法在 __new__方法的基础上完成一些初始化工作&#xff0c;不需要返回值。 __new__(cls)是一个静态方法&#xff0c;当实例化一…

【Redis】SSM整合Redis注解式缓存的使用

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《Redis》。&#x1f3af;&#x1f3af; &#x1f4…

C++特殊类与单例模式

一、特殊类 类的特殊设计方式 ①不能被拷贝的类 拷贝只会放生在两个场景中&#xff1a;拷贝构造函数以及赋值运算符重载&#xff0c;因此想要让一个类禁止拷贝&#xff0c; 只需让该类不能调用拷贝构造函数以及赋值运算符重载即可 在C98中&#xff0c;需要将拷贝构造设置成…

uni-app android picker选择默认月份

微信小程序选中月份后下次再点开是上次的选中的月份&#xff0c;而编译的android应用只默认当前月份 <picker mode"date" ref"picker" :disabled"disabled" :value"date" fields"month" change"bindDateChange&quo…

【ML】分类问题

分类问题 classification&#xff1a;根据已知样本特征&#xff0c;判断输入样本属于哪种已知样本类。 常用入门案例&#xff1a;垃圾邮件检测、图像分类、手写数字识别、考试通过预测。 分类问题和回归问题的明显区别&#xff1a; 分类问题的结果是非连续型标签&#xff0c…

Netty入门指南之传统通信的问题

作者简介&#xff1a;☕️大家好&#xff0c;我是Aomsir&#xff0c;一个爱折腾的开发者&#xff01; 个人主页&#xff1a;Aomsir_Spring5应用专栏,Netty应用专栏,RPC应用专栏-CSDN博客 当前专栏&#xff1a;Netty应用专栏_Aomsir的博客-CSDN博客 文章目录 参考文献前言多线程…

基于APM(PIX)飞控和missionplanner制作遥控无人车-从零搭建自主pix无人车无人坦克

前面的步骤和无人机调试一样&#xff0c;可以参考无人机相关专栏。这里不再赘述。 1.安装完rover的固件后&#xff0c;链接gps并进行校准。旋转小车不同方向&#xff0c;完成校准&#xff0c;弹出成功窗口。 2.校准遥控器。 一定要确保遥控器模式准确&#xff0c;尤其是使用没…

轻量封装WebGPU渲染系统示例<20>- 美化一下元胞自动机(源码)

当前示例源码github地址: https://github.com/vilyLei/voxwebgpu/blob/feature/rendering/src/voxgpu/sample/GameOfLifePretty.ts 系统特性: 1. 用户态与系统态隔离。 2. 高频调用与低频调用隔离。 3. 面向用户的易用性封装。 4. 渲染数据(内外部相关资源)和渲染机制分离…