当前位置: 首页 > article >正文

中介者模式(Mediator Pattern)详解

文章目录

    • 1. 中介者模式概述
      • 1.1 定义
      • 1.2 基本思想
    • 2. 中介者模式的结构
    • 3. 中介者模式的UML类图
    • 4. 中介者模式的工作原理
    • 5. Java实现示例
      • 5.1 基本实现示例
      • 5.2 飞机空中交通控制示例
      • 5.3 GUI应用中的中介者模式
    • 6. 中介者模式的优缺点
      • 6.1 优点
      • 6.2 缺点
    • 7. 中介者模式的适用场景
    • 8. 中介者模式在框架中的应用
      • 8.1 Java Swing中的应用
      • 8.2 Spring框架中的应用
    • 9. 中介者模式与其他设计模式的区别与联系
      • 9.1 中介者模式与观察者模式
      • 9.2 中介者模式与外观模式
      • 9.3 中介者模式与命令模式
    • 10. 实战案例:智能家居控制系统
    • 11. 总结

1. 中介者模式概述

1.1 定义

中介者模式是一种行为型设计模式,它通过一个中介对象来封装一系列对象之间的交互。中介者使各个对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

1.2 基本思想

中介者模式的核心思想是:

  • 将对象间的复杂交互关系转换为星形结构
  • 对象之间不再直接通信,而是通过中介者对象协调完成
  • 减少了对象间的相互依赖,降低了系统的耦合度

2. 中介者模式的结构

中介者模式包含以下角色:

  • 抽象中介者(Mediator):定义了同事对象到中介者对象的接口
  • 具体中介者(ConcreteMediator):实现抽象中介者的方法,协调各个同事对象来实现协作行为
  • 抽象同事类(Colleague):定义了同事类的接口,保存对中介者对象的引用
  • 具体同事类(ConcreteColleague):实现抽象同事类的方法,每个具体同事类只知道自己的行为,而不了解其他同事类的情况

3. 中介者模式的UML类图

┌───────────────┐         ┌───────────────────┐
│ <<interface>> │         │    Colleague      │
│    Mediator   │◄────────├───────────────────┤
├───────────────┤         │ -mediator:Mediator│
│+notifyColleague()│      │ +setMediator()    │
└───────┬───────┘         │ +send()           ││                 └─────────┬─────────┘│                           ││                           │
┌───────▼───────┐       ┌───────────┴─────────────┐
│ConcreteMediator│       │                         │
├───────────────┤       │                         │
│-colleagues    │       │                         │
│+notifyColleague()│    │                         │
└───────────────┘   ┌───▼───────────┐     ┌───────▼─────────┐│ConcreteColleague1│     │ConcreteColleague2│├─────────────────┤     ├─────────────────┤│+send()          │     │+send()          ││+receive()       │     │+receive()       │└─────────────────┘     └─────────────────┘

4. 中介者模式的工作原理

  1. 各个同事对象持有对中介者对象的引用
  2. 当一个同事对象需要与其他同事对象交互时,它通过中介者对象发送消息
  3. 中介者对象接收到消息后,决定将消息转发给哪些同事对象
  4. 其他同事对象接收到中介者对象转发的消息,并作出响应
  5. 整个交互过程中,各个同事对象只与中介者对象交互,而不直接与其他同事对象通信

5. Java实现示例

5.1 基本实现示例

下面是一个简单的中介者模式实现示例,模拟用户之间通过聊天室(中介者)进行交流:

import java.util.ArrayList;
import java.util.List;// 抽象中介者
interface ChatMediator {void sendMessage(String message, User user);void addUser(User user);
}// 抽象同事类
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 receive(String message);
}// 具体中介者
class ChatRoom implements ChatMediator {private List<User> users;public ChatRoom() {this.users = new ArrayList<>();}@Overridepublic void addUser(User user) {this.users.add(user);}@Overridepublic void sendMessage(String message, User user) {// 将消息发送给除了发送者之外的所有用户for (User u : users) {if (u != user) {u.receive(message);}}}
}// 具体同事类
class ChatUser extends User {public ChatUser(ChatMediator mediator, String name) {super(mediator, name);}@Overridepublic void send(String message) {System.out.println(this.name + " 发送消息: " + message);mediator.sendMessage(message, this);}@Overridepublic void receive(String message) {System.out.println(this.name + " 收到消息: " + message);}
}// 客户端代码
public class MediatorPatternDemo {public static void main(String[] args) {ChatMediator chatRoom = new ChatRoom();User user1 = new ChatUser(chatRoom, "张三");User user2 = new ChatUser(chatRoom, "李四");User user3 = new ChatUser(chatRoom, "王五");chatRoom.addUser(user1);chatRoom.addUser(user2);chatRoom.addUser(user3);user1.send("大家好!");System.out.println("---------");user2.send("张三你好!");}
}

5.2 飞机空中交通控制示例

下面是一个模拟飞机着陆控制塔作为中介者协调多架飞机的例子:

import java.util.ArrayList;
import java.util.List;// 抽象中介者
interface AirTrafficControlMediator {void registerFlight(Flight flight);void registerRunway(Runway runway);boolean isRunwayAvailable();void setRunwayStatus(boolean status);void notifyFlightLanded();
}// 抽象同事类
interface Command {void execute();
}// 抽象飞行器
abstract class Flight {protected AirTrafficControlMediator mediator;public Flight(AirTrafficControlMediator mediator) {this.mediator = mediator;}public abstract void land();
}// 机场跑道类
class Runway {private AirTrafficControlMediator mediator;public Runway(AirTrafficControlMediator mediator) {this.mediator = mediator;mediator.registerRunway(this);}public void setStatus(boolean status) {mediator.setRunwayStatus(status);}
}// 具体中介者
class AirTrafficControlTower implements AirTrafficControlMediator {private Flight flight;private Runway runway;private boolean runwayAvailable;public AirTrafficControlTower() {runwayAvailable = true;}@Overridepublic void registerFlight(Flight flight) {this.flight = flight;}@Overridepublic void registerRunway(Runway runway) {this.runway = runway;}@Overridepublic boolean isRunwayAvailable() {return runwayAvailable;}@Overridepublic void setRunwayStatus(boolean status) {runwayAvailable = status;}@Overridepublic void notifyFlightLanded() {System.out.println("跑道现在可用");setRunwayStatus(true);}
}// 具体飞行器:航班
class CommercialFlight extends Flight {private String flightNumber;public CommercialFlight(AirTrafficControlMediator mediator, String flightNumber) {super(mediator);this.flightNumber = flightNumber;mediator.registerFlight(this);}@Overridepublic void land() {if (mediator.isRunwayAvailable()) {System.out.println("商业航班 " + flightNumber + " 成功着陆。");mediator.setRunwayStatus(false);// 模拟飞机着陆后离开跑道new Thread(() -> {try {Thread.sleep(3000); // 假设飞机需要3秒离开跑道mediator.notifyFlightLanded();} catch (InterruptedException e) {e.printStackTrace();

相关文章:

中介者模式(Mediator Pattern)详解

文章目录 1. 中介者模式概述1.1 定义1.2 基本思想2. 中介者模式的结构3. 中介者模式的UML类图4. 中介者模式的工作原理5. Java实现示例5.1 基本实现示例5.2 飞机空中交通控制示例5.3 GUI应用中的中介者模式6. 中介者模式的优缺点6.1 优点6.2 缺点7. 中介者模式的适用场景8. 中介…...

Linux系统(OpenEuler22.03-LTS)部署FastGPT

在 openEuler 22.03 LTS 系统上通过 Docker Compose 安装 FastGPT 的步骤如下&#xff1a; 官方参考文档&#xff1a;https://doc.fastgpt.cn/docs/development/docker/ 1. 安装 Docker 和 Docker Compose 可以参考我之前离线安装Docker的文章&#xff1a;openEuler 22.03 LT…...

Kubernetes控制平面组件:Controller Manager 之 内置Controller详解

云原生学习路线导航页&#xff08;持续更新中&#xff09; kubernetes学习系列快捷链接 Kubernetes架构原则和对象设计&#xff08;一&#xff09;Kubernetes架构原则和对象设计&#xff08;二&#xff09;Kubernetes架构原则和对象设计&#xff08;三&#xff09;Kubernetes控…...

结合Splash与Scrapy:高效爬取动态JavaScript网站

在当今的Web开发中&#xff0c;JavaScript的广泛应用使得许多网站的内容无法通过传统的请求-响应模式直接获取。为了解决这个问题&#xff0c;Scrapy开发者经常需要集成像Splash这样的JavaScript渲染引擎。本文将详细介绍Splash JS引擎的工作原理&#xff0c;并探讨如何将其与S…...

用于构建安全AI代理的开源防护系统

大家读完觉得有帮助记得及时关注&#xff01;&#xff01;&#xff01; 大型语言模型&#xff08;LLMs&#xff09;已经从简单的聊天机器人演变为能够执行复杂任务的自主代理&#xff0c;例如编辑生产代码、编排工作流程以及基于不受信任的输入&#xff08;如网页和电子邮件&am…...

算法与数据结构 - 常用图算法总结

在图论中&#xff0c;图算法非常重要&#xff0c;广泛应用于计算机科学、网络分析、社交网络、地理信息系统等领域。下面是一些常用的图算法&#xff0c;按不同功能和应用场景分类&#xff1a; 1. 图的遍历 图遍历算法用于遍历图中的节点和边。主要有两种常见的图遍历方法&am…...

克里金模型+多目标优化+多属性决策!Kriging+NSGAII+熵权TOPSIS!

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 克里金模型多目标优化多属性决策&#xff01;KrigingNSGAII熵权TOPSIS&#xff01;&#xff01;matlab2023b语言运行&#xff01; 1.克里金模型&#xff08;Kriging Model&#xff09;是一种基于空间统计学的插值方法…...

LLM 论文精读(三)Demystifying Long Chain-of-Thought Reasoning in LLMs

这是一篇2025年发表在arxiv中的LLM领域论文&#xff0c;主要描述了长思维链 Long Chain-of-Thought 对LLM的影响&#xff0c;以及其可能的生成机制。通过大量的消融实验证明了以下几点&#xff1a; 与shot CoT 相比&#xff0c;long CoT 的 SFT 可以扩展到更高的性能上限&…...

【Prompt工程—文生图】案例大全

目录 一、人物绘图 二、卡通头像 三、风景图 四、logo设计图 五、动物形象图 六、室内设计图 七、动漫风格 八、二次元图 九、日常场景图 十、古风神化图 十一、游戏场景图 十二、电影大片质感 本文主要介绍了12种不同类型的文生图技巧&#xff0c;通过加入不同的图像…...

本地可执行命令的智能体部署方案

本地可执行命令的智能体部署方案&#xff0c;目标是让大语言模型&#xff08;LLM&#xff09;在本地接收自然语言指令&#xff0c;并自动调用系统命令、脚本或应用程序&#xff0c;完成任务自动化。这类系统通常被称为 LLM Agent with Tool Use 或 本地 Agent 实体系统。 &…...

rust程序静态编译的两种方法总结

1. 概述 经过我的探索&#xff0c;总结了两种rust程序静态编译的方法,理论上两种方法都适用于windows、mac os和linux(mac os未验证)&#xff0c;实测方法一性能比方法二好&#xff0c;现总结如下&#xff0c;希望能够帮到你. 2.方法一 2.1 添加配置文件 在项目的同级文件夹下新…...

验证码(笔记)

为什么要有验证码&#xff1a; 为什么验证码这么让人厌烦&#xff0c;每个网站还要使用它呢&#xff1f;换句话说&#xff0c;这些网站为什么要“故意为难”用户呢&#xff1f; 其实验证码主要是为了区分用户是计算机还是人。假设一个黑客知道了你的账号&#xff0c;根据账号可…...

【Linux系列】目录大小查看

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

2048游戏(含Python源码)

前言 相关参考游戏&#xff1a; 像素飞机大战&#xff08;含Python源码&#xff09;-CSDN博客https://blog.csdn.net/weixin_64066303/article/details/147693018?spm1001.2014.3001.5501使用DeepSeek定制Python小游戏——以“俄罗斯方块”为例-CSDN博客https://blog.csdn.n…...

SwiftData 数据持久化解决方案

什么是 SwiftData&#xff1f; SwiftData 是苹果在 WWDC23 上推出的全新数据持久化框架&#xff0c;它构建在 Core Data 之上&#xff0c;但提供了更加 Swift 友好的 API。SwiftData 旨在简化数据模型的创建和管理&#xff0c;让开发者能够以更少的代码实现强大的数据持久化功…...

中间件-RocketMQ

RocketMQ 基本架构消息模型消费者消费消息模式顺序消息机制延迟消息批量消息事务消息消息重试最佳实践 基本架构 nameServer: 维护broker列表信息&#xff0c;客户端连接时只需要连接nameServer。可配置成集群。 broker&#xff1a;broker分为master和slave&#xff0c;master负…...

PostgreSQL 的 pg_current_logfile 函数

PostgreSQL 的 pg_current_logfile 函数 pg_current_logfile() 是 PostgreSQL 9.6 版本引入的一个系统管理函数&#xff0c;用于获取当前正在使用的日志文件路径。 一 基本用法 1 函数定义 pg_current_logfile([text]) → text2 简单查询 -- 获取当前日志文件路径 SELECT …...

Python就业方向有哪些?

Python 作为一门通用、易学且功能强大的编程语言&#xff0c;在多个领域都有广泛的应用&#xff0c;因此就业方向也非常多样化。以下是 Python 主要的就业方向及相关技能要求。 1. Web 开发 岗位&#xff1a;Python Web 开发工程师、后端工程师、全栈工程师技术栈&#xff1a…...

iptables 访问控制列表使用记录

iptables 是linux操作系统上自带的防火墙程序&#xff0c;功能强大&#xff0c;能够依据策略过滤掉一些恶意访问流量&#xff0c;本次记录一下iptables的常见使用方法&#xff0c;未尽之处&#xff0c;欢迎补充。 一、iptables 下载 我这里使用的是华为openEuler 22.03版本&am…...

16. Qt系统相关:事件、定时器

1. Qt事件 1.1 简介 事件是应用程序内部或者外部产生的事情或者动作的统称。在Qt中使用一个对象来表示一个事件。所有的Qt事件均继承于抽象类QEvent。事件是由系统或者Qt平台本身在不同的时刻发出的。当用户按下鼠标、敲下键盘&#xff0c;或者是窗口需要重新绘制的时候&#…...

云平台搭建

物联网云平台的基本概述 基本概念 随着物联网技术的快速发展&#xff0c;越来越多的设备需要接入网络以实现智能化功能&#xff0c;物联网平台应运而生。 物联网云平台&#xff08;IoT Cloud Platform&#xff09;是物联网生态系统中的核心组件&#xff0c;它通过提供一系列…...

数学实验(Matlab语言环境和线性代数实验)

一、Matlab语言环境和线性代数实验 1.Matlab语言环境 Matlab简介 Matlab&#xff1a;Matrix Laboratry 矩阵实验室 Matlab 提供了强大的科学计算、灵活的程序设计流程、高质量的图形可视化与界面设计等功能&#xff0c;被广泛应用于科学计算、控制系统、信息处理等领域的分…...

sherpa:介绍

更多内容&#xff1a;XiaoJ的知识星球 目录 1. sherpa 介绍 1. sherpa 介绍 sherpa是 Next-gen Kaldi 项目的部署框架。 sherpa 支持在各种平台上部署与语音相关的预训练模型&#xff0c;并提供多种语言绑定。 目前&#xff0c;sherpa 拥有以下子项目&#xff1a; k2-fsa/sh…...

图片上传的util和使用

图片上传的util package com.ruoyi.web.controller.common.utils;import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.spri…...

2025年4月个人工作生活总结

本文为 2025年4月工作生活总结。 研发编码 一个项目的临时记录 自2月份领导让我牵头负责一个项目起&#xff0c;在本月算是有较多时间投入——但也是与之前的相比。 月初&#xff0c;清明节前一晚上&#xff0c;因某事务被叫上参加临时紧急远程会议&#xff0c;几方领导都在…...

利用Elixir中的原子特性 + 错误消息泄露 -- Atom Bomb

题目信息: This new atom bomb early warning system is quite strange… 题目使用 elixir 语言 一开始,我们会访问 /page.html <!DOCTYPE html> <!-- 设定文档语言为英语 --> <html lang"en"> <head><!-- 设定字符编码为UTF-8 --><…...

numpy pandas

视频链接 numpy numpy是基于一个矩阵的运算 矩阵的属性 import numpy as np# 把一个列表转换成矩阵的方法 array np.array([[1,2,3],[3,4,5]])# 打印矩阵 print(array)# 维度 print(number of dim:,array.ndim)# 行数和列数 print(shape:,array.shape)# 总共有多少个元素在…...

Amazon Redshift 使用场景解析与最佳实践

作为 AWS 云上数据仓库服务的核心成员&#xff0c;Amazon Redshift 凭借其高性能、可扩展性与经济性&#xff0c;正在成为越来越多企业实现数据驱动决策的首选方案。本文将解析 Redshift 的典型使用场景&#xff0c;并分享几项实用的落地最佳实践&#xff0c;帮助企业在数据仓库…...

STM32F446 RTC在VDD/VDDA关闭后失振问题的分析与解决

【原创】STM32F446 RTC在VDD/VDDA关闭后失振问题的分析与解决 作者: 思考的味道[你的ID] | weix_42368227 版权声明: 禁止未经授权转载 1. 问题描述 在某低功耗STM32F446项目中&#xff0c;采用以下供电方案&#xff1a; VDD&#xff1a;由DC-DC 3.3V提供&#xff08;主电源…...

SSM框架(Spring + Spring MVC + MyBatis)整合配置的详细步骤

以下是 SSM框架&#xff08;Spring Spring MVC MyBatis&#xff09;整合配置的详细步骤&#xff0c;适用于 Maven 项目。 &#xff08;一&#xff09;、pom.xml中添加相关依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"ht…...