设计模式-中介者模式在Java中使用示例-客户信息管理
场景
欲开发客户信息管理窗口界面,界面组件之间存在较为复杂的交互关系:如果删除一个客户,
要在客户列表(List)中删掉对应的项,客户选择组合框(ComboBox)中客户名称也将减少一个;
如果增加一个客户信息,客户列表中需增加一个客户,且组合框中也将增加一项。
中介者模式概述
如果在一个系统中对象之间的联系呈现为网状结构。对象之间存在大量的多对多联系,将导致系统非常复杂,
这些对象既会影响别的对象,也会被别的对象所影响,这些对象称为同事对象,它们之间通过彼此的相互作用
实现系统的行为。在网状结构中,几乎每个对象都需要与其他对象发生相互作用,而这种相互作用表现为一个
对象与另外一个对象的直接耦合,这将导致一个过度耦合的系统。
中介者模式可以使对象之间的关系数量急剧减少,通过引入中介者对象,可以将系统的网状结构变成以中介者
为中心的星形结构。在这个星形结构中,同事对象不再直接与另一个对象联系,它通过中介者对象与
另一个对象发生相互作用。中介者对象的存在保证了对象结构上的稳定,也就是说,系统的结构不会因为
新对象的引入带来大量的修改工作。
中介者模式结构图

在中介者模式结构图中包含如下几个角色:
Mediator(抽象中介者):
它定义一个接口,该接口用于与各同事对象之间进行通信。
ConcreteMediator(具体中介者):
它是抽象中介者的子类,通过协调各个同事对象来实现协作行为,它维持了对各个同事对象的引用。
Colleague(抽象同事类):
它定义各个同事类公有的方法,并声明了一些抽象方法来供子类实现,同时它维持了一个对抽象中介者类
的引用,其子类可以通过该引用来与中介者通信。
ConcreteColleague(具体同事类):
它是抽象同事类的子类;每一个同事对象在需要和其他同事对象通信时,先与中介者通信,
通过中介者来间接完成与其他同事类的通信;在具体同事类中实现了在抽象同事类中声明的抽象方法。
注:
博客:
霸道流氓气质_C#,架构之路,SpringBoot-CSDN博客
实现
使用中介者模式实现客户信息管理页面。
1、新建抽象中介者
//抽象中介者
abstract class Mediator {public abstract void componentChanged(Component component);
}
2、然后新建具体中介者,维持对各个同事对象的引用
//具体中介者
public class ConcreteMediator extends Mediator{//维持对各个同事对象的引用public Button addButton;public UserList userList;public TextBox userNameTextBox;public ComboBox cb;@Overridepublic void componentChanged(Component c) {//单击按钮if(c == addButton){System.out.println("单击增加按钮");userList.update();cb.update();userNameTextBox.update();}else if(c == userList){System.out.println("从列表框选择客户");cb.select();userNameTextBox.setText();}else if(c == cb){System.out.println("从组合框选择客户");cb.select();userNameTextBox.setText();}}
}
3、新建抽象组件类:抽象同事类
//抽象组件类:抽象同事类
abstract class Component {protected Mediator mediator;public void setMediator(Mediator mediator){this.mediator = mediator;}//转发调用public void changed(){mediator.componentChanged(this);}public abstract void update();
}
4、新建具体同事类:按钮类
//按钮类:具体同事类
public class Button extends Component{public void update() {System.out.println("列表增加一项");}public void select(){System.out.println("列表框选中项");}
}
5、新建具体同事类:组合框类
//组合框类:具体同事类
public class ComboBox extends Component{public void update() {System.out.println("组合框增加一项");}public void select(){System.out.println("组合框选中项");}
}
6、新建具体同事类:文本框类
//文本框类:具体同事类
public class TextBox extends Component{public void update() {System.out.println("客户信息增加成功后文本框清空");}public void setText(){System.out.println("文本框显示");}
}
7、新建具体同事类:列表框类
//列表框类:具体同事类
public class UserList extends Component{public void update() {System.out.println("列表框增加一项");}public void select(){System.out.println("列表框选中项");}
}
8、客户端调用方式如下
public class Client {public static void main(String[] args) {//定义中介者对象ConcreteMediator mediator;mediator = new ConcreteMediator();//定义同事对象Button addBT = new Button();UserList userList = new UserList();ComboBox cb = new ComboBox();TextBox userNameTB = new TextBox();addBT.setMediator(mediator);userList.setMediator(mediator);cb.setMediator(mediator);userNameTB.setMediator(mediator);mediator.addButton = addBT;mediator.userList = userList;mediator.cb = cb;mediator.userNameTextBox = userNameTB;addBT.changed();userList.changed();}
}
9、总结
中介者模式将一个网状的系统结构变成一个以中介者对象为中心的星形结构,在这个星型结构中,
使用中介者对象与其他对象的一对多关系来取代原有对象之间的多对多关系。
中介者模式在事件驱动类软件中应用较为广泛,特别是基于GUI(Graphical User Interface,图形用户界面)
的应用软件,此外,在类与类之间存在错综复杂的关联关系的系统中,中介者模式都能得到较好的应用。
中介者模式的主要优点如下:
(1) 中介者模式简化了对象之间的交互,它用中介者和同事的一对多交互代替了原来同事之间的多对多交互,
一对多关系更容易理解、维护和扩展,将原本难以理解的网状结构转换成相对简单的星型结构。
(2) 中介者模式可将各同事对象解耦。中介者有利于各同事之间的松耦合,我们可以独立的改变和复用
每一个同事和中介者,增加新的中介者和新的同事类都比较方便,更好地符合“开闭原则”。
(3) 可以减少子类生成,中介者将原本分布于多个对象间的行为集中在一起,改变这些行为只需生成新的
中介者子类即可,这使各个同事类可被重用,无须对同事类进行扩展。
中介者模式的主要缺点如下:
在具体中介者类中包含了大量同事之间的交互细节,可能会导致具体中介者类非常复杂,使得系统难以维护。
在以下情况下可以考虑使用中介者模式:
(1) 系统中对象之间存在复杂的引用关系,系统结构混乱且难以理解。
(2) 一个对象由于引用了其他很多对象并且直接和这些对象通信,导致难以复用该对象。
(3) 想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。可以通过引入中介者类来
实现,在中介者中定义对象交互的公共行为,如果需要改变行为则可以增加新的具体中介者类。
相关文章:
设计模式-中介者模式在Java中使用示例-客户信息管理
场景 欲开发客户信息管理窗口界面,界面组件之间存在较为复杂的交互关系:如果删除一个客户, 要在客户列表(List)中删掉对应的项,客户选择组合框(ComboBox)中客户名称也将减少一个; 如果增加一个客户信息,…...
14443-1-doc
介绍 ISO/IEC 14443 是描述 ISO/IEC 7810 中定义的身份证参数以及此类卡在国际交换中的使用的一系列国际标准之一。 ISO/IEC 14443 的这一部分描述了感应卡的物理特性。 ISO/IEC 14443 的这一部分并不排除在卡上纳入其他标准技术,例如资料性附录 A 中引用的技术。非…...
SpringBoot的三层架构以及IOCDI
目录 一、IOC&DI入门 二、三层架构 数据库访问层 业务逻辑层 控制层 一、IOC&DI入门 在软件开发中,IOC(Inversion of Control)和DI(Dependency Injection)是密切相关的概念。 IOC(控制反转&a…...
RabbitMQ部署指南
RabbitMQ部署指南 1.单机部署 我们在Centos7虚拟机中使用Docker来安装。 1.1.下载镜像 方式一:在线拉取 docker pull rabbitmq:3-management方式二:从本地加载 已经提供了镜像包: 上传到虚拟机中后,使用命令加载镜像即可&…...
【Golang】Golang进阶系列教程--Go 语言切片是如何扩容的?
文章目录 前言声明和初始化扩容时机源码分析go1.17go1.18内存对齐 总结 前言 在 Go 语言中,有一个很常用的数据结构,那就是切片(Slice)。 切片是一个拥有相同类型元素的可变长度的序列,它是基于数组类型做的一层封装…...
【数据结构】顺序表(SeqList)(增、删、查、改)详解
一、顺序表的概念和结构 1、顺序表的概念: 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。 2、顺序表的结构: (1)静态顺序表:使…...
[golang gin框架] 42.Gin商城项目-微服务实战之后台Rbac微服务角色增删改查微服务
一.重构后台Rbac用户登录微服务功能 上一节讲解了后台Rbac微服务用户登录功能以及Gorm数据库配置单独抽离,Consul配置单独抽离,这一节讲解后台Rbac微服务角色增删改查微服务功能,Rbac微服务角色增删改查微服务和后台Rbac用户登录微服务是属于…...
项目篇:Echo论坛系统项目
一、登录注册模块 1、注册功能 1.1、注册流程图 1.2、注册代码 /*** 用户注册* param user* return Map<String, Object> 返回错误提示消息,如果返回的 map 为空,则说明注册成功*/public Map<String, Object> register(User user) {Map&l…...
数据可视化(2)
1.柱状图 #柱状图 #bar(x,height,width,*,aligncenter,**kwargs) #height柱子的高度,即y轴上的数据 #width数组的宽度,默认值0.8 #*表示后面的参数为匿名关键字,必须传入参数 #kwargs关键字参数x[1,2,3,4,5] height[random.randint(10,100)f…...
MD-MTSP:斑马优化算法ZOA求解多仓库多旅行商问题MATLAB(可更改数据集,旅行商的数量和起点)
一、斑马优化算法ZOA 斑马优化算法(Zebra Optimization Algorithm,ZOA)Eva Trojovsk等人于2022年提出,其模拟斑马的觅食和对捕食者攻击的防御行为。斑马优化算法(Zebra Optimization Algorithm,ZOA&#x…...
【笔试强训选择题】Day32.习题(错题)解析
作者简介:大家好,我是未央; 博客首页:未央.303 系列专栏:笔试强训选择题 每日一句:人的一生,可以有所作为的时机只有一次,那就是现在!! 文章目录 前言 一、Da…...
抖音seo账号矩阵系统源码如何开发布局?
目录 一、 抖音SEO账号矩阵系统源码的开发布局步骤如下: 二。 开发部署源码 三、 开发部署功能设计 1. 短视频AI智能创作 2. 托管式账号管理: 3. 数据分析 4. 智能营销获客 四。 抖音seo源码开发部署交付技术文档包含 五。 开发代码展示: 一、 抖…...
vue项目cdn打包优化
0.用vue ui可以查看项目打包后的情况。 1.定义包的排除 let externals {axios: axios,element-ui: ELEMENT,echarts: echarts,} configureWebpack: {externals: externals }2.配置cdn包资源 // 配置 let cdn {css: [// element-ui csshttps://unpkg.com/element-ui/lib/th…...
Android 之 MediaPlayer 播放音频与视频
本节引言: 本节带来的是Android多媒体中的——MediaPlayer,我们可以通过这个API来播放音频和视频 该类是Androd多媒体框架中的一个重要组件,通过该类,我们可以以最小的步骤来获取,解码 和播放音视频。它支持三种不同的…...
React中事件处理器的基本使用
在React中,为了提高性能,跨浏览器兼容性和开发体验,React实现了一套自己的事件机制,利用事件委托和合成事件的方式统一管理事件订阅和分发。 为了让组件能够响应用户的交互行为,React提供了一系列的事件处理器…...
RobotFramework
一、RobotFramework的简介和特点 1、关键字驱动: 把项目中的业务逻辑封装成一个一个的关键字,然后调用不同的关键字组成不同的业务 2、数据驱动 把测试数据放到excel:yaml文件中 通过改变文件中的数据去驱动测试用例执行 3、特点ÿ…...
【Matplotlib 绘制折线图】
使用 Matplotlib 绘制折线图 在数据可视化中,折线图是一种常见的图表类型,用于展示随着变量的变化,某个指标的趋势或关系。Python 的 Matplotlib 库为我们提供了方便易用的功能来绘制折线图。 绘制折线图 下面的代码展示了如何使用 Matplo…...
ARM汇编基本变量的定义和使用
一、ARM汇编中基本变量是什么? 数字变量: GBLA LCLA SETA 逻辑变量:GBLL LCLL SETL 字符串:GBLS LCLS SETLS 注意需要TAB键定义变量和行首改变值 二、使用步骤 1.引入库 代码如下(示例): GBLA led_num Reset_Handler PROCEXPORT Reset_Handler [WEA…...
排序算法汇总
每日一句:你的日积月累终会成为别人的望尘莫及 目录 常数时间的操作 选择排列 冒泡排列 【异或运算】 面试题: 1)在一个整形数组中,已知只有一种数出现了奇数次,其他的所有数都出现了偶数次,怎么找到…...
cocos2d 中UserDefault在windows平台下的路径问题
在使用cocos2dx c开发项目时,通常使用cocos自带的UserDefault来存储一些项目所用到的一些配置信息:如游戏的音量,游戏的闯关数等... 但是windows平台下,测试发现如果用户的帐户名使用是中文,在启动程序时会报错&#…...
别再只用SSH了!给CentOS 7.9服务器装上图形桌面,用VNC远程操作真香
解锁CentOS 7.9图形化运维:VNC远程桌面实战指南在Linux服务器管理的日常工作中,纯命令行操作虽然高效,但遇到复杂的文件管理、图形化工具调试或团队协作时,图形界面往往能事半功倍。本文将带您从零开始,为CentOS 7.9服…...
MCP插件下载403故障排查:OAuth 2026白名单机制详解
1. 问题现场还原:为什么MCP插件下载页面总卡在403 Forbidden?你点开MCP(Model Control Platform)官方插件市场,选中一个标注“支持v2.8”的调试工具,点击“下载ZIP”,浏览器控制台立刻弹出Faile…...
告别SystemTap:为什么Linux内核开发者更偏爱ftrace?从原理到实战对比
告别SystemTap:为什么Linux内核开发者更偏爱ftrace?从原理到实战对比在Linux内核开发与性能优化领域,调试工具的选型往往决定了问题排查的效率与系统稳定性。当面对偶发的调度延迟或难以复现的内核异常时,开发人员需要在低开销、高…...
Drupal YAML反序列化RCE漏洞CVE-2017-6920深度解析
1. 这不是“又一个RCE”,而是一次对Drupal架构信任边界的彻底重写2017年3月,Drupal官方发布安全通告,编号CVE-2017-6920,定级为Critical(严重),CVSS评分高达9.8。当时我正在给一家省级政务平台做…...
从原理到操作:彻底搞懂Linux服务器UEFI启动项管理(efibootmgr命令详解)
深入解析Linux服务器UEFI启动管理:efibootmgr命令全攻略当你在Linux服务器上执行efibootmgr命令时,是否曾被那些神秘的Boot000X条目搞得一头雾水?作为现代服务器的主流启动方式,UEFI远比传统的BIOS复杂得多。本文将带你从底层原理…...
TT100K数据集类别不平衡?手把手教你用Python筛选并重划分(保留45类实战)
TT100K数据集类别不平衡解决方案:Python实战指南当你第一次打开TT100K数据集时,可能会被其庞大的图片数量震撼——train文件夹6105张,test文件夹3071张,other文件夹更是多达7641张。但兴奋过后,细看类别分布࿰…...
SPSS+Excel搞定SCI必备技能:零代码绘制Logistic回归亚组交互效应图
SPSSExcel零代码绘制Logistic回归亚组交互效应图:临床研究者的可视化救星"统计结果显著,但图表被审稿人打回重做"——这可能是临床研究者最头疼的问题之一。亚组交互效应分析作为高分SCI文章的"黄金标配",其可视化呈现直…...
Redis 缓存实战案例与技术详解
Redis 缓存实战案例与技术详解 1. Redis 简介 Redis 是一种开源的内存数据存储,常用于缓存和消息队列。 2. 配置优化 使用 LRU 淘汰策略配置数据持久化功能 3. 实战案例 案例一:电商秒杀系统 架构:前端系统 Redis 持久化缓存特点:…...
股市学习心得-技术指标学习(布林线+MACD)
技术指标学习(布林线MACD)(所提供内容仅用于学习交流,不作为股市交易依据)首先,技术指标除了量比和换手率,都有滞后和造假的可能,因此不能用单一指标判断,也需要通过多个指标辅助决策。布林线MA…...
通过curl命令快速测试Taotoken的API连通性与返回
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 通过curl命令快速测试Taotoken的API连通性与返回 在集成大模型服务时,直接使用curl命令进行API测试是一种高效且通用的…...
