Java行为型模式---中介者模式

中介者模式基础概念

中介者模式(Mediator Pattern)是一种行为型设计模式,其核心思想是通过一个中介对象来封装一系列对象之间的交互,使各对象不需要显式地相互引用,从而降低耦合度,并可以独立地改变它们之间的交互。中介者模式将多对多的交互转化为一对多的交互,集中控制对象间的通信。

中介者模式的核心组件

  1. 抽象中介者(Mediator) - 定义中介者与同事对象之间的通信接口。
  2. 具体中介者(ConcreteMediator) - 实现抽象中介者接口,协调各同事对象之间的交互,持有所有同事对象的引用。
  3. 抽象同事类(Colleague) - 定义同事类的公共接口,每个同事对象都知道其中介者对象,并通过中介者进行通信。
  4. 具体同事类(ConcreteColleague) - 实现抽象同事类,只知道中介者而不知道其他同事对象,通过中介者与其他同事通信。

中介者模式的实现

下面通过一个简单的聊天室示例展示中介者模式的实现:

// 1. 抽象中介者
interface ChatMediator {void sendMessage(String message, User user);void addUser(User user);
}// 2. 具体中介者 - 聊天室
class ChatRoom implements ChatMediator {private List<User> users = new ArrayList<>();@Overridepublic void sendMessage(String message, User user) {// 中介者负责消息的转发for (User u : users) {if (u != user) {  // 不发送给自己u.receiveMessage(message);}}}@Overridepublic void addUser(User user) {users.add(user);}
}// 3. 抽象同事类 - 用户
abstract class User {protected ChatMediator mediator;protected String name;public User(ChatMediator mediator, String name) {this.mediator = mediator;this.name = name;}public abstract void send(String message);public abstract void receiveMessage(String message);
}// 4. 具体同事类 - 普通用户
class NormalUser extends User {public NormalUser(ChatMediator mediator, String name) {super(mediator, name);}@Overridepublic void send(String message) {System.out.println(name + " 发送消息: " + message);mediator.sendMessage(message, this);  // 通过中介者发送消息}@Overridepublic void receiveMessage(String message) {System.out.println(name + " 收到消息: " + message);}
}// 5. 具体同事类 - VIP用户
class VIPUser extends User {public VIPUser(ChatMediator mediator, String name) {super(mediator, name);}@Overridepublic void send(String message) {System.out.println("[VIP] " + name + " 发送消息: " + message);mediator.sendMessage("[VIP] " + message, this);  // VIP消息添加特殊标识}@Overridepublic void receiveMessage(String message) {System.out.println(name + " 收到消息: " + message);}
}// 6. 客户端代码
public class MediatorPatternClient {public static void main(String[] args) {// 创建中介者ChatMediator chatRoom = new ChatRoom();// 创建同事对象User user1 = new NormalUser(chatRoom, "张三");User user2 = new NormalUser(chatRoom, "李四");User user3 = new VIPUser(chatRoom, "王五");// 将同事添加到中介者chatRoom.addUser(user1);chatRoom.addUser(user2);chatRoom.addUser(user3);// 发送消息user1.send("大家好!");System.out.println();user3.send("欢迎加入聊天室!");}
}

中介者模式的应用场景

  1. 系统中对象间依赖复杂 - 当对象间存在大量的相互引用和交互,导致依赖关系混乱时
  2. 集中控制交互 - 需要集中控制多个对象间的交互逻辑时
  3. MVC 架构 - 控制器(Controller)作为视图(View)和模型(Model)的中介
  4. GUI 组件交互 - 如窗口中多个组件间的联动
  5. 消息队列系统 - 消息中间件作为生产者和消费者的中介
  6. 多人游戏 - 游戏服务器作为玩家之间的中介,处理消息转发

中介者模式的优缺点

优点

  • 降低耦合度 - 对象间无需显式引用,减少了对象间的依赖关系
  • 集中控制交互 - 将交互逻辑集中在中介者中,便于维护和修改
  • 符合开闭原则 - 可以在不修改现有同事类的情况下,通过扩展中介者类来新增交互方式
  • 简化对象协议 - 将多对多的交互转化为一对多的交互,简化了通信协议
  • 便于复用 - 单个同事类可以在不同的中介者环境中复用

缺点

  • 中介者类膨胀 - 中介者承担了过多的交互逻辑,可能变得复杂庞大
  • 维护难度增加 - 中介者类的修改可能影响多个同事类,增加维护风险
  • 系统响应变慢 - 所有交互都通过中介者,可能导致系统响应性能下降
  • 违反单一职责原则 - 中介者类可能负责过多的功能,导致职责不清晰
  • 调试困难 - 中介者中的交互逻辑可能复杂,导致调试困难

使用中介者模式的注意事项

  1. 控制中介者复杂度 - 避免中介者类过于庞大,可将部分逻辑分解为更小的组件
  2. 合理设计中介者接口 - 确保中介者接口清晰,不包含无关功能
  3. 避免过度使用 - 仅在对象间交互复杂且需要集中控制时使用中介者模式
  4. 与观察者模式结合 - 中介者模式可以与观察者模式结合,实现事件驱动的交互
  5. 考虑性能影响 - 对于高性能要求的系统,需谨慎使用中介者模式
  6. 测试中介者 - 由于中介者集中了大量逻辑,应对其进行充分测试

总结

中介者模式通过引入一个中介对象来封装对象间的交互,将多对多的依赖关系转化为一对多的关系,从而降低系统的耦合度,提高可维护性和可扩展性。它在需要集中控制对象交互的场景中尤为有用,如 GUI 系统、消息队列、多人游戏等。合理使用中介者模式可以使系统结构更加清晰,但需注意控制中介者类的复杂度,避免其成为系统的瓶颈。

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

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

相关文章

Python爬虫实战:研究Korean库相关技术

一、引言 1.1 研究背景与意义 随着韩流文化在全球的传播,韩语网页内容急剧增加。韩国在科技、娱乐等领域的信息具有重要研究价值。然而,韩语独特的黏着语特性(如助词体系、词尾变化)给信息处理带来挑战。传统爬虫缺乏对韩语语言特点的针对性处理,本研究旨在开发一套完整…

表单校验--数组各项独立校验

写需求时遇到一个这样的问题&#xff0c;就是校样项是多个的&#xff0c;但是其字段名称相同这时我们可以这样校验&#xff0c;注意字段之间的关联性<div v-for"(item,index) in formData.hospitalDoctorList" :key"item.key || index"><el-form-…

基于SpringBoot和leaflet-timeline-slider的历史叙事GIS展示-以哪吒2的海外国家上映安排为例

目录 前言 一、哪吒2的海外之路 1、海外征战历程 2、上映国家空间查询 二、后端接口的实现 1、模型层的实现 2、上映时间与国家 3、控制层的实现 三、基于leaflet-timeline-slider的前端实现 1、时间轴控件的引入及定义 2、时间轴绑定事件 3、成果展示 四、总结 前言…

tar 解压:Cannot change ownership to uid 1000, gid 1000: Operation not permitted

tar 解压 tar.gz 压缩包报错&#xff1a; # tar xzf $INPUT_FOLDER/archive.tar.gz -C /mnt/test-nas/[..] tar: xx.jpg: Cannot change ownership to uid 1000, gid 1000: Operation not permitted原因是用普通用户执行的解压缩脚本&#xff0c;用root用户执行tar解压缩&…

腾讯客户端开发面试真题分析

以下是针对腾讯客户端开发工程师面试问题的分类与高频问题分析&#xff08;基于​​105道问题&#xff0c;总出现次数118次​​&#xff09;。按技术领域整合为​​7大类别​​&#xff0c;按占比排序并精选高频问题标注优先级&#xff08;1-5&#x1f31f;&#xff09;&#x…

线上问题排查之【CPU飙高100%】

目录 案例 发现问题 排查问题 步骤一 步骤二 步骤三 案例 import java.util.concurrent.TimeUnit;/*** 简单写一个CPU飙高的案例*/ public class CpuLoadUp {// 这里定义了一个标识private volatile static int flag 0;public static void main(String[] args) {// 执行…

c语言 进阶 动态内存管理

动态内存管理1. 为什么存在动态内存分配2. 动态内存函数的介绍​2.1 malloc 和 freemalloc 函数free 函数2.2内存泄漏2.3 calloc2.4 realloc3. 常见的动态内存错误3.1 对NULL指针的解引用操作3.2 对动态开辟空间的越界访问3.3 对非动态开辟内存使用free释放3.4 使用free释放一块…

Redis的五大基本数据类型

一、Redis基本知识与Redis键&#xff08;key&#xff09;常用操作命令。redis的默认端口6379。mysql默认端口号3306。 默认16个数据库&#xff0c;类似数组的下标从0开始&#xff0c;初始默认使用0号库。可以使用select index来切换数据库&#xff0c;如&#xff1a;select 1&a…

达梦数据库JSON_TABLE使用说明

在达梦数据库&#xff08;DM Database&#xff09;中&#xff0c;将 JSON 数据转换为表格形式可以使用内置的 JSON_TABLE 函数。以下是详细步骤和示例&#xff1a;1. 核心函数&#xff1a;JSON_TABLE JSON_TABLE 用于将 JSON 数据解析为关系表结构&#xff0c;支持从 JSON 对象…

A316-1926-V1 USB多路高清音频解码器模组技术解析

随着数字音频技术的不断发展&#xff0c;高品质音频解决方案的需求日益增长。本文将介绍一款基于XMOS技术的高性能USB音频解码器模组——A316-1926-V1&#xff0c;这是一款专为高清音频应用设计的专业模组。核心技术与特性A316-1926-V1是一款集成了多项先进技术的USB多路高清音…

.NET 8 中的 KeyedService

.NET 8 中的 KeyedService&#xff1a;新特性解析与使用示例 一、引言 在 .NET 8 的 Preview 7 版本中&#xff0c;引入了 KeyedService 支持。这一特性为开发者提供了按名称&#xff08;name&#xff09;获取服务的便利&#xff0c;在某些场景下&#xff0c;开发者无需再自行…

Paimon对比基于消息队列(如Kafka)的传统实时数仓方案的优势

弊端&#xff1a;数据重复 -> 优势&#xff1a;Paimon 主键表原生去重原方案弊端 (Kafka)问题: 消息队列&#xff08;Kafka&#xff09;是仅支持追加&#xff08;Append-Only&#xff09;的日志流。当 Flink 作业发生故障恢复&#xff08;Failover&#xff09;或业务逻辑迭代…

Linux Shell 命令 + 项目场景

shell 命令1. 基础文件操作命令1.1 ls - 列出目录内容1.2 find - 文件搜索2. 版本控制命令2.1 git - 版本控制系统2.2 高级 Git 操作3. 文本搜索命令3.1 grep - 文本搜索3.2 高级搜索技巧4. Android 构建系统命令4.1 source - 加载环境变量4.2 lunch - 选择构建目标4.3 m - And…

A316-Mini-V1:超小尺寸USB高清音频解码器模组技术探析

引言 随着便携式音频设备的普及&#xff0c;对小型化、高性能音频解决方案的需求日益增长。本文将介绍一款极致小型化的高性能USB音频解码器模组——A316-Mini-V1&#xff0c;这是一款基于XMOS XU316芯片的微型音频处理模组。产品概述 A316-Mini-V1是一款专为小尺寸产品设计的M…

低代码平台买saas好还是私有化好

选择低代码平台采用SaaS还是私有化部署&#xff0c;应根据企业具体情况考虑安全性、成本控制、维护难度、扩展需求等因素。 其中&#xff0c;安全性是决定企业选择的重要因素之一。私有化部署意味着企业能够完全掌控数据和系统的安全管理&#xff0c;更适合对数据安全要求极高的…

基于SkyWalking的微服务APM监控实战指南

基于SkyWalking的微服务APM监控实战指南 1. 业务场景描述 随着微服务在生产环境中大规模应用&#xff0c;系统链路复杂、实例弹性伸缩、灰度发布等特点都给性能监控和问题诊断带来了新的挑战。传统的单机或轻量级监控方案已无法满足微服务环境下的全链路、分布式追踪和实时告警…

Python 进阶(五): Excel 基本操作

目录 1. 概述2. 写入 2.1 使用 xlwt2.2 使用 XlsxWriter 3. 读取4. 修改 1. 概述 在现实中&#xff0c;很多工作都需要与数据打交道&#xff0c;Excel 作为常用的数据处理工具&#xff0c;一直备受人们的青睐&#xff0c;而大部分人都是手动操作 Excel&#xff0c;如果数据量…

32、鸿蒙Harmony Next开发:使用动画-动画概述

​​​属性动画转场动画粒子动画组件动画动画曲线动画衔接动画效果帧动画&#xff08;ohos.animator&#xff09; UI&#xff08;用户界面&#xff09;中包含开发者与设备进行交互时所看到的各种组件&#xff08;如时间、壁纸等&#xff09;。属性作为接口&#xff0c;用于控制…

【STM32】485接口原理

485 通信实验 这篇文章是对 RS485通信 的原理、硬件连接、接口芯片&#xff08;SP3485&#xff09;、总线结构等都有详尽的说明。我们在此处进行清晰有条理的讲解整理&#xff0c;便于学习和实验操作。 在了解485接口通信原理之前&#xff0c;我们先复习一下串口&#xff1a;串…

亚马逊二审攻防全攻略:预防、应对与长效合规之道

当店铺收到二审通知&#xff0c;不少卖家会陷入焦虑与慌乱&#xff0c;只要掌握科学的预防策略与应对方法&#xff0c;不仅能降低二审风险&#xff0c;即便遭遇审核也能顺利突围。一、未雨绸缪&#xff1a;预防二审的四大核心策略夯实资料真实性根基资料的真实性与一致性是亚马…