Java设计模式之中介者模式(Mediator Pattern)

Java设计模式之中介者模式(Mediator Pattern)

引言

在软件开发中,设计模式是解决常见设计问题的一系列最佳实践。中介者模式(Mediator Pattern)是行为型设计模式之一,它的主要目的是减少对象之间的直接相互作用,从而降低它们之间的耦合度。通过引入一个中介者对象来管理对象间的交互,中介者模式让对象之间的通信变得更加简单和灵活。本文将深入探讨中介者模式的概念、结构、优点、缺点、应用场景以及在Java中的实现方式。

中介者模式概述

中介者模式定义了一个中介对象来封装一系列对象之间的交互。这种模式使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。在中介者模式中,中介者负责处理对象间的通信和协作,对象间不再直接交互,而是通过中介者来间接通信。

结构

中介者模式主要包含以下几个角色:

  1. 中介者(Mediator)

    • 定义了对象间交互的接口。
    • 维护一系列对象(同事对象),并协调它们之间的交互。
    • 可以是抽象类或接口,也可以是具体类。
  2. 同事类(Colleague)

    • 持有中介者的引用。
    • 在需要与其他同事通信时,通过中介者来间接通信。
    • 可以是抽象类或接口,也可以是具体类。
优点
  1. 降低耦合度:通过中介者对象来管理对象间的交互,减少了对象间的直接引用,降低了系统的耦合度。
  2. 易于维护:当系统需要扩展或修改时,只需修改中介者或增加新的中介者类,而无需修改同事类,提高了系统的可维护性。
  3. 易于控制交互:中介者可以集中控制同事之间的交互行为,如限制某些交互、添加日志记录等。
  4. 提高灵活性:由于对象间的交互由中介者控制,因此可以轻松地改变系统的交互方式,而无需修改大量代码。
缺点
  1. 可能产生中介者过度复杂:如果系统中对象间的交互非常复杂,那么中介者对象可能会变得非常复杂和庞大,增加了系统的理解和维护难度。
  2. 可能产生中介者依赖:由于所有对象间的交互都通过中介者进行,因此中介者对象可能成为系统的关键节点,一旦中介者出现问题,可能会影响整个系统的运行。
应用场景
  1. 对象间存在复杂交互:当多个对象之间存在复杂的交互关系,且这些交互关系经常变化时,可以使用中介者模式来管理这些交互。
  2. 系统需要高内聚低耦合:在设计系统时,为了提高系统的内聚性和降低系统的耦合度,可以使用中介者模式来封装对象间的交互细节。
  3. 需要集中控制交互行为:如果系统需要集中控制对象间的交互行为,如限制某些交互、添加日志记录等,可以使用中介者模式来实现。
Java实现

下面是一个简单的Java示例,演示了中介者模式的实现。在这个示例中,我们创建了一个聊天室系统,其中包含了多个用户(同事类)和一个聊天室(中介者类)。用户之间通过聊天室进行通信。

// 中介者接口
interface ChatRoom {void showMessage(User user, String message);
}// 具体中介者实现
class ConcreteChatRoom implements ChatRoom {private List<User> users = new ArrayList<>();@Overridepublic void showMessage(User user, String message) {for (User u : users) {if (!u.equals(user)) {u.receive(message);}}}public void addUser(User user) {users.add(user);}
}// 同事类接口
interface User {void send(String message);void receive(String message);
}// 具体同事类实现
class ConcreteUser implements User {private String name;private ChatRoom chatRoom;public ConcreteUser(String name, ChatRoom chatRoom) {this.name = name;this.chatRoom = chatRoom;chatRoom.addUser(this);}@Overridepublic void send(String message) {System.out.println(name + ": " + message);chatRoom.showMessage(this, "[" + name + "] " + message);}@Overridepublic void receive(String message) {System.out.println(name + " received: " + message);}
}// 测试类
public当然,以下是继续编写的Java代码,展示如何使用中介者模式来创建一个简单的聊天室系统。我们将添加一个测试类来演示如何使用`ConcreteChatRoom`和`ConcreteUser`类。```java
// 测试类
public class ChatRoomDemo {public static void main(String[] args) {// 创建中介者对象ChatRoom chatRoom = new ConcreteChatRoom();// 创建并注册用户User user1 = new ConcreteUser("Alice", chatRoom);User user2 = new ConcreteUser("Bob", chatRoom);User user3 = new ConcreteUser("Charlie", chatRoom);// 用户发送消息user1.send("Hello everyone!");user2.send("Hi Alice, how are you?");user3.send("Good to see you all!");// 注意:在实际应用中,通常不需要显式地调用receive方法,// 因为showMessage方法已经在中介者内部调用了它。// 这里只是为了演示User接口的实现而包含receive方法。}
}// 注意:确保ConcreteUser类中的send方法正确调用了chatRoom的showMessage方法,
// 并且receive方法已经按上述方式实现。// ConcreteUser类(已在上文中定义,这里再次展示以确保完整性)
class ConcreteUser implements User {private String name;private ChatRoom chatRoom;public ConcreteUser(String name, ChatRoom chatRoom) {this.name = name;this.chatRoom = chatRoom;chatRoom.addUser(this); // 注册用户到聊天室}@Overridepublic void send(String message) {System.out.println(name + ": " + message); // 显示本地消息chatRoom.showMessage(this, "[" + name + "] " + message); // 发送消息到聊天室}@Overridepublic void receive(String message) {System.out.println(name + " received: " + message); // 接收并显示消息}
}// ConcreteChatRoom类(已在上文中定义,无需重复)
// ...// User接口(已在上文中定义,无需重复)
// ...// ChatRoom接口(已在上文中定义,无需重复)
// ...

在这个示例中,ChatRoomDemo类是我们的测试类,它创建了一个ConcreteChatRoom对象作为中介者,并创建了三个ConcreteUser对象作为同事类(即聊天室的用户)。每个用户都通过调用send方法来发送消息,该方法内部调用了中介者的showMessage方法,将消息广播给除了发送者之外的所有用户。由于showMessage方法内部调用了每个用户的receive方法,因此每个用户都能接收到其他用户发送的消息。

请注意,在实际应用中,receive方法通常不需要由外部代码显式调用,因为中介者已经负责在适当的时候调用它。然而,在这个示例中,我们包含了receive方法的实现,以便更清楚地展示User接口的实现细节。

运行ChatRoomDemo类的main方法将输出类似于以下内容的消息,展示了聊天室中用户之间的交互:

Alice: Hello everyone!
Bob received: [Alice] Hello everyone!
Charlie received: [Alice] Hello everyone!
Bob: Hi Alice, how are you?
Alice received: [Bob] Hi Alice, how are you?
Charlie received: [Bob] Hi Alice, how are you?
Charlie: Good to see you all!
Alice received: [Charlie] Good to see you all!
Bob received: [Charlie] Good to see you all!

这样,我们就完成了一个简单的基于中介者模式的聊天室系统的实现。

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

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

相关文章

kubeadm搭建生产环境高可用集群

前言 搞了好多天&#xff08;今天是20240819&#xff09;&#xff0c;中途遇到各种各样的问题&#xff0c;总算是可以用了 我这里用的vmware开了5台服务器做学习实践 K8S因为直接使用的 pkgs.k8s.io 仓库&#xff0c;所以直接拉取的最新release版&#xff08;v1.31&#xff09…

SIRA-PCR: Sim-to-Real Adaptation for 3D Point Cloud Registration 论文解读

目录 一、导言 二、 相关工作 1、三维点云配准工作 2、无监督域适应 三、SIRA-PCR 1、FlyingShape数据集 2、Sim-to-real自适应方法 3、配准 4、损失函数 一、导言 该论文来自于ICCV2023&#xff0c;论文提出了一种新的方法SIRA-PCR&#xff0c;通过利用合成数据Flying…

网易云音乐故障 2 小时,这次到底谁背锅?(今天记得领补偿)

大家好&#xff0c;我是程序员鱼皮&#xff0c;8 月 19 日下午&#xff0c;网易云音乐突发严重故障&#xff0c;并登顶微博热搜&#xff0c;跟黑神话悟空抢了热度。 根据用户的反馈&#xff0c;故障的具体表现为&#xff1a;用户无法登录、歌单加载失败、播放信息获取失败、无法…

了解数据库中常用存储引擎数据结构(2)

目录 深入了解B树及其变种 BTree BTree B*Tree BTree并发机制 B-Link Tree 深入了解B树及其变种 先把我们要解释的B树变种都列出来&#xff0c;B树的变种主要有B树、B*树、B-Link树、COW B树、惰性B树、Bw树等。 下面具体来分析这些变种的优势和发展趋势。 BTree 下图…

Taro+Vue 创建微信小程序

TaroVue 创建微信小程序 一、全局安装 tarojs/cli二、项目初始化三、现在去启动项目吧 一、全局安装 tarojs/cli npm install -g tarojs/cli //安装 npm info tarojs/cli //查看安装信息 如果正常显示版本说明成功了&#xff0c;就直接跳到第二步吧官网说&#xff1a;…

AI产品经理如何入门?零基础入门到精通,收藏这一篇就够了

现在做产品经理&#xff0c;真的挺累的。 现在产品越来越难做&#xff0c;晋升困难&#xff0c;工资迟迟不涨……公司裁员&#xff0c;产品经理首当其冲&#xff01;&#xff01; 做产品几年了&#xff0c;还没升职&#xff0c;就先到了“职业天花板”。 想凭工作几年积累的…

BFS解决单源最短路问题

目录 迷宫中离入口最近的出口 最小基因变化 单词接龙 为高尔夫比赛砍树 迷宫中离入口最近的出口 题目 思路 使用宽度优先遍历解决这道题&#xff0c;需要一个二维数组标记是否被遍历过&#xff0c;也需要一个队列辅助完成宽度优先遍历&#xff0c;类似于水波纹一样&#x…

JAVA基础:File类

目录 前言 file对象的创建 file的常用方法 前言 file类表示的是系统中的一个文件或者文件夹 file类和系统中的文件或者文件夹不需要是一一对应的&#xff0c;我们可以在file类中写你系统中不存在的文件或文件夹 file类中存储的实际上是文件或文件夹的抽象路径&#xff0c…

面试经典算法150题系列-最长公共前缀

最长公共前缀 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀&#xff0c;返回空字符串 ""。 示例 1&#xff1a; 输入&#xff1a;strs ["flower","flow","flight"] 输出&#xff1a;"fl"示例 2&…

ShardingSphere、雪花算法、分布式id生成器CosID概述

ShardingSphere 用处&#xff1a;sharding是分片的意思&#xff0c;sphere是球&#xff08;生态的意思&#xff09;。用来做分库分表的生态的。一个订单表太大&#xff0c;查询会很慢&#xff0c;要分表&#xff0c;分为3个表&#xff0c;这样查询会快一点&#xff0c;所以有了…

软件测试 - 自动化测试(概念)(Java)(自动化测试分类、web自动化测试、驱动、selenium自动化测试工具的安装)

一、自动化的概念 ⾃动洒⽔机&#xff0c;主要通上⽔就可以⾃动化洒⽔并且可以⾃动的旋转。 ⾃动洗⼿液&#xff0c;免去了⼿动挤压可以⾃动感应出洗⼿液 超市⾃动闸⻔&#xff0c;不需要⼿动的开⻔关⻔ ⽣活中的⾃动化案例有效的减少了⼈⼒的消耗&#xff0c;同时也提⾼了⽣…

C语言程序设计(初识C语言后部分)

代码是一门艺术&#xff0c;键盘是我的画笔。 3.递归和迭代&#xff08;循环就是一种迭代&#xff0c;迭代不仅仅是循环&#xff09; 求n&#xff01; 递归方式&#xff1a; n!---> 1 (n1); n*(n-1)! (n>1) #include <stdio.h> //n!-->递归方式 int fac(in…

Kafka运行机制(一):Kafka集群启动,controller选举,生产消费流程

前置知识 Kafka基本概念https://blog.csdn.net/dxh9231028/article/details/141270920?spm1001.2014.3001.5501 1. Kafka集群启动 Kafka在启动集群中的各个broker时&#xff0c;broker会向controller注册自己&#xff0c;并且从controller节点同步集群元数据。 broker是Kaf…

C++入门——16C++11新特性

1.列表初始化 初始化列表时&#xff0c;可添加等号()&#xff0c;也可不添加。 struct Point {int _x;int _y; };int main() {int x1 1;int x2{ 2 };int array1[]{ 1, 2, 3, 4, 5 };int array2[5]{ 0 };Point p{ 1, 2 };// C11中列表初始化也可以适用于new表达式中int* pa …

SpringBoot文档之Profiles的阅读笔记

Reference Core Features Profiles 类似Maven的Profile特性&#xff0c;限定配置项取值的生效场景。 在代码中&#xff0c;对于使用注解Component、Configuration、ConfigurationProperties标记的类&#xff0c;可以增加Profile&#xff0c;限定前述类的生效场景。 类似如下样…

jstack结果提取特定线程池线程的堆栈

这里假设你已经知道如何定位java进程PID&#xff0c;以及如何执行jstack命令进行导出&#xff0c;下面仅提供相关命令&#xff0c;及示例 ps aux|grep java jstack 8229 > jstack_output.log v1版本 grep second jstack_output.log 如果此时我们想重点关注一下下面这个线程…

Spark大数据分析案例

目录 案例概述环境搭建1. Spark单机环境2. Spark集群环境 数据集数据预处理 Spark作业编写提交Spark作业 数据可视化可能遇到的问题及解决方法结论 案例概述 本案例将介绍如何在单机和集群环境下使用Apache Spark进行大数据分析&#xff0c;最终使用Python实现数据的可视化。我…

高性价比全屋智能家居解决方案,提升生活幸福感!

在快节奏的城市生活中&#xff0c;公司、住宅两点一线的上班族不在少数。近年来&#xff0c;随着物联网、大数据技术的不断发展与5G的广泛普及&#xff0c;生活品质的提升成为上班族新的关注焦点。忙碌的工作时间结束后&#xff0c;智慧家居系统打造便捷、安全、智能、舒适的居…

32-hashmap linkedmap treemap 的区别

‌HashMap‌、‌LinkedHashMap‌和‌TreeMap‌是Java中三种常用的Map实现&#xff0c;它们在数据结构、有序性、性能和线程安全性等方面有所不同。 ‌数据结构‌&#xff1a; ‌HashMap‌&#xff1a;基于哈希表数据结构实现&#xff0c;通过计算键的哈希值来确定存储位置。它不…

ptrade排坑日记——定时任务执行后,文件权限会变化。

前言 今天要和大家分享的是使用ptrade的定时任务过后&#xff0c;执行的时候&#xff0c;文件权限会发生变化&#xff01; 一、问题描述 定时任务执行后&#xff0c; /home/fly/data/fundamentals_daily/all.pickle、/home/fly/data/valuation_new/all.pickle 文件权限会从…