【设计模式-4.8】行为型——中介者模式

说明:本文介绍行为型设计模式之一的中介者模式

定义

中介者模式(Mediator Pattern)又叫作调节者模式或调停者模式。用一个中介对象封装一系列对象交互,中介者使各对象不需要显式地互相作用,从而使其耦合松散,而且可以独立地改变它们之间的交互,属于行为型设计模式。

(引自《设计模式就该这样学》P376)

中介者模式简单来说,就是引入中间层,让多对多关系,转为多个一对多关系,图示如下:

(多对多场景)

在这里插入图片描述

(引入中间层,转为多个一对多)

在这里插入图片描述

这样符合迪米特法则(指一个软件实体应当尽可能少地与其他实体发生相互作用),这样,当一个模块修改时,就会尽量少地影响其他的模块。

通讯交友

以两人通讯为例,如下,

(用户类,User)

/*** 用户类*/
public class User {/*** 自己的名字*/private String name;/*** 定义通话对方*/private User friend;public User(String name) {this.name = name;}public String getName() {return name;}/*** 建立连接*/public void connect(User friend) {this.friend = friend;}/*** 说话* 我方说话,调用对方的listen方法*/public void talk(String msg) {friend.listen(msg);}/*** 接听*/private void listen(String msg) {System.out.println(friend.name + " 对 " + name + " 说:" + msg);}
}

(客户端使用,进行聊天)

public class Client {public static void main(String[] args) {User zhangsan = new User("zhangsan");User lisi = new User("lisi");zhangsan.connect(lisi);lisi.connect(zhangsan);zhangsan.talk("hello,四哥,我是三哥啊,您最近挺好的啊?");lisi.talk("哦,三哥啊,我以为谁呢,我挺好的,您呢?");}
}

开始通话

在这里插入图片描述

现在只有两个人,这种设计看起来没有问题,但如果有十个人,开一场多人会议,就要在对象内维护一个User集合,而会议人数新增或减少时,要同时改动每个对象中的User集合,这非常繁琐还容易出问题。

聊天室

基于上面代码的问题,我们引入一个中间层(聊天室),如下:

(用户类,User,定义一个所属聊天室)

/*** 用户类*/
public class User {/*** 自己的名字*/private String name;/*** 所属聊天室*/private Chatroom chatRoom;public User(String name) {this.name = name;}public String getName() {return name;}/*** 加入群聊*/public void login(Chatroom chatRoom) {this.chatRoom = chatRoom;chatRoom.register(this);}/*** 群内发言*/public void talk(String msg) {chatRoom.sendMsg(this, msg);}/*** 接收消息*/public void listen(User fromUser, String msg) {System.out.println("【" + this.name + "】的聊天框 【" + fromUser.getName()  + "】说:" + msg);}
}

(聊天室,用来管理群成员,发消息等操作)

import java.util.ArrayList;
import java.util.List;/*** 聊天室*/
public class Chatroom {/*** 群名称*/private String name;public Chatroom(String name) {this.name = name;}/*** 群内好友*/private List<User> users = new ArrayList<>();/*** 好友加入群聊*/public void register(User user) {this.users.add(user);System.out.println("【系统消息】" + user.getName() + "进入群聊");}/*** 群内发消息*/public void sendMsg(User fromUser, String msg) {users.stream().forEach(user -> user.listen(fromUser, msg));System.out.println("-------------------------------------------------");}
}

(客户端测试,Client)

public class Client {public static void main(String[] args) {// 创建群,好友Chatroom chatroom = new Chatroom("各位IT界的大佬们");User zhangsan = new User("zhangsan");User lisi = new User("lisi");User wangwu = new User("王五");// 好友加入群聊zhangsan.login(chatroom);lisi.login(chatroom);// 发消息zhangsan.talk("hello,四哥,群里就你一个人啊");lisi.talk("是啊,把五哥拉进来");// 拉人进群wangwu.login(chatroom);// 发消息zhangsan.talk("哇,五哥来了");wangwu.talk("哥几个,怎么说");}
}

怎么样,这样设计是不是好多了,结构一下就稳定了,无论群成员增加还是减少,现有代码都不用改动。

在这里插入图片描述

使用场景

在《设计模式就该这样学》(P378)这本书中,提到状态模式适用于以下场景:

(1)系统中对象之间存在复杂的引用关系,产生的相互依赖关系结构混乱且难以理解。

(2)交互的公共行为,如果需要改变行为,则可以增加新的中介者类。

中介者模式,在Java三层结构开发中就有体现,Service层不会直接访问数据库,而是抽出DAO层,使用DAO对象访问数据库,就是中介者模式的一种体现,还有Spring IOC容器也是,将Bean的创建使用抽离出来统一管理。

还有,有时我们业务中,有种业务场景,没有与之对应的实体(像User对应UserService、UserDAO),而是业务逻辑中产生的对象,如CheckService(检查服务,根据日志表、用户表,检查用户状态是否正常),我们不直接在UserService里实现,而是抽出一个CheckService,这也是中介者模式的一种实现。

总结

本文介绍了行为型设计模式中的中介者模式,参考《设计模式就该这样学》、《秒懂设计模式》两书,通讯交友、聊天室场景是《秒懂设计模式》中的举例。

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

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

相关文章

Oracle 的 SEC_CASE_SENSITIVE_LOGON 参数

Oracle 的SEC_CASE_SENSITIVE_LOGON 参数 关键版本信息 SEC_CASE_SENSITIVE_LOGON 参数在以下版本中被弃用&#xff1a; Oracle 12c Release 1 (12.1)&#xff1a; 该参数首次被标记为"过时"(obsolete)但依然保持功能有效 Oracle 18c/19c 及更高版本&#xff1a; …

《图解技术体系》How Redis Architecture Evolves?

Redis架构的演进经历了多个关键阶段&#xff0c;从最初的内存数据库发展为支持分布式、多模型和持久化的高性能系统。以下为具体演进路径&#xff1a; 单线程模型与基础数据结构 Redis最初采用单线程架构&#xff0c;利用高效的I/O多路复用&#xff08;如epoll&#xff09;处…

【电赛培训课】测量与信号类赛题分析

一、赛题基本情况及硬件电路准备 &#xff08;一&#xff09;赛题基本情况 1.测量与信号类赛题统计 2.测量与信号类赛题特点 &#xff08;二&#xff09;硬件电路准备 综测环节不允许带入电脑和手机&#xff0c;需要自己根据题目要求和芯片参数指标进行设计和计算&#xff0c…

移动AI神器GPT Mobile:多模型自由切换

GPT Mobile是什么 GPT Mobile是一款开源的本地移动部署AI工具,主要用于安卓设备。以下是其相关介绍: 功能特点 多模型交互:支持与多个大型语言模型(LLM)同时进行对话,用户导入相应的API密钥,就可连接OpenAI、Anthropic、Google、Ollama等平台,还能根据需求自由切换不同…

AirSim/Cosys-AirSim 游戏开发(二)使用自定义场景

在实际的开发过程中很少会只用 AirSim 自带的 Blocks 场景&#xff0c;通常需要用到自定义的一些环境和模型&#xff0c;依托于强大的 UE 引擎可以较为逼真地完成场景渲染。这篇博客记录了如何从头开始导入一个自定义场景并加载 AirSim 插件。 【Note】&#xff1a;由于 UE Ed…

GPU 图形计算综述 (三):可编程管线 (Programmable Pipeline)

2000年左右&#xff0c;微软在DirectX 8.0中首次提出了Shader Model 1.0和顶点着色器&#xff08;Vertex Shader&#xff09;的概念&#xff0c;标志着可编程管线时代的来临。随后&#xff0c;在DirectX 9.0中推出了Shader Model 2.0和像素着色器&#xff08;Pixel Shader&…

【Go语言基础【3】】变量、常量、值类型与引用类型

文章目录 一、值&#xff08;Value&#xff09;与字面量&#xff08;Literal&#xff09;1. 值2. 字面量 二、变量&#xff08;Variable&#xff09;1. 声明方式2. 赋值方式3. 变量默认值4. 类型与值的匹配 三、常量&#xff08;Constant&#xff09;1. 声明方式2. 常量的特性3…

AWS 亚马逊 S3存储桶直传 前端demo 复制即可使用

自己踩过坑不想别人也踩坑了 亚马逊S3存储桶直传前端demo复制即可使用 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0…

Python数据可视化科技图表绘制系列教程(四)

目录 带基线的棒棒糖图1 带基线的棒棒糖图2 带标记的棒棒糖图 哑铃图1 哑铃图2 包点图1 包点图2 雷达图1 雷达图2 交互式雷达图 【声明】&#xff1a;未经版权人书面许可&#xff0c;任何单位或个人不得以任何形式复制、发行、出租、改编、汇编、传播、展示或利用本博…

如何有效删除 iPhone 上的所有内容?

“在出售我的 iPhone 之前&#xff0c;我该如何清除它&#xff1f;我担心如果我卖掉它&#xff0c;有人可能会从我的 iPhone 中恢复我的信息。” 升级到新 iPhone 后&#xff0c;你如何处理旧 iPhone&#xff1f;你打算出售、以旧换新还是捐赠&#xff1f;无论你选择哪一款&am…

[yolov11改进系列]基于yolov11使用SwinTransformer替换backbone用于提高多尺度特征提取能力的python源码+训练源码

【SwinTransformer介绍】 摘要 ViT的缺点&#xff1a; Transformer在语言处理中的基本元素是word token&#xff0c;其特点是语义信息比较密集。而ViT中token的尺度&#xff08;scale&#xff09;是固定的&#xff0c;且视觉token携带的语义信息比语言文字序列差&#xff0c…

NoSQL 之 Redis 配置与优化

目录 一、Redis 介绍 1、关系型数据库与非关系型数据库 &#xff08;1&#xff09;关系型数据库 &#xff08;2&#xff09;非关系型数据库 &#xff08;3&#xff09;非关系型数据库产生背景 2、Redis 基础 &#xff08;1&#xff09;Redis 简介 &#xff08;2&#x…

算法复杂度,咕咕咕

1.数据结构与算法 数据结构是计算机存储&#xff0c;组织数据的方式&#xff0c;指相互之间存在一种或多种特定关系的数据元素的集合。可以理解为形状不同的容器。 算法是定义好的计算过程&#xff0c;取输入值&#xff0c;经过一系列计算方法变成输出值。 &#xff08;推荐…

【Linux】 Linux 进程控制

参考博客&#xff1a;https://blog.csdn.net/sjsjnsjnn/article/details/125581083 一、进程创建 1.1 fork()函数 在linux中fork函数是非常重要的函数&#xff0c;它从已存在进程中创建一个新进程。新进程为子进程&#xff0c;而原进程为父进程。进程调用fork&#xff0c;当…

【大模型】MCP是啥?它和点菜、做菜、端菜有啥关系?

什么是 Model Context Protocol (MCP)? Model Context Protocol(模型上下文协议),通俗来说,就是一套用来管理、传递和维护对话或交互中上下文信息的规则和格式标准。 换句话说,MCP定义了模型在处理用户输入和生成回答时,如何理解、保留和传递上下文信息的协议,确保对…

机器学习的数学基础:决策树

决策树 文章目录 决策树决策树的基本思想划分选择信息增益增益率基尼指数 减枝处理回归问题对连续值的处理对缺失值的处理 决策树的基本思想 决策树是基于树结构来进行决策的&#xff0c;通过对问题的判断与决策&#xff0c;得到最终决策。 一般的&#xff0c;决策树包括一个…

基于若依前后分离版-用户密码错误锁定

sys_config配置参数 user.password.maxRetryCount&#xff1a;最大错误次数 user.password.lockTime&#xff1a;锁定时长 //SysLoginController//登录 PostMapping("/login") public AjaxResult login(RequestBody LoginBody loginBody) {AjaxResult ajax AjaxR…

Java线程安全集合类

Java线程安全集合类全面解析 目录 并发集合概述List线程安全实现Set线程安全实现Map线程安全实现Queue线程安全实现总结 并发集合概述 Java提供了多种线程安全的集合类&#xff0c;主要分为两大类&#xff1a; 传统同步集合&#xff1a;通过synchronized关键字实现线程安全…

汇川变频器MD600S-4T-5R5为什么要搭配GRJ9000S-10-T滤波器?

一、变频器的工作原理与电磁干扰 汇川MD600S-4T-5R5变频器是一款紧凑型高性能变频器&#xff0c;适用于三相380V-480V电网&#xff0c;额定电流5.5A&#xff0c;支持矢量控制和多种编码器接口&#xff0c;适用于需要高精度速度和转矩控制的场景&#xff0c;如机器人、电梯、纺…

数学运算在 OpenCV 中的核心作用与视觉效果演示

在计算机视觉中&#xff0c;图像不仅仅是我们肉眼所见的内容&#xff0c;它其实是由数值矩阵组成的“数据”。而在 OpenCV&#xff08;Open Source Computer Vision Library&#xff09;中&#xff0c;正是数学运算赋予了图像处理无限的可能——从基本的滤波、增强到复杂的特征…