软件设计模式系列之十九——中介者模式

news2024/12/25 12:40:17

中介者模式目录

  • 1 模式的定义
  • 2 举例说明
  • 3 结构
  • 4 实现步骤
  • 5 代码实现
  • 6 典型应用场景
  • 7 优缺点
  • 8 类似模式
  • 9 小结

1 模式的定义

中介者模式是一种行为型设计模式,它用于降低对象之间的直接通信,通过引入一个中介者对象来管理对象之间的交互。这种模式有助于减少对象之间的耦合性,使系统更加可维护和扩展。中介者模式是Gang of Four(GoF)设计模式中的一员,旨在促进对象之间的松耦合关系,从而提高系统的灵活性。

2 举例说明

为了更好地理解中介者模式,让我们考虑一个简单的例子:一个多人在线聊天室应用程序。在这个应用程序中,有多个用户可以发送消息给其他用户,而不需要直接知道接收消息的用户是谁。中介者模式可以用来管理用户之间的消息传递。
在这里插入图片描述

在这个例子中,中介者充当聊天室的中心,所有用户都将消息发送到中介者,然后中介者负责将消息传递给适当的接收者。这样,用户之间不需要直接通信,而是通过中介者进行通信,从而降低了用户之间的耦合性。

3 结构

中介者模式的结构包括以下几个关键元素:
在这里插入图片描述

抽象中介者(Mediator):这是中介者模式的核心接口,它定义了中介者对象应该具备的方法,通常包括注册组件、发送消息等操作。

具体中介者(ConcreteMediator):具体中介者是抽象中介者的实现,它维护了对所有相关组件的引用,并负责协调它们之间的通信。

抽象组件(Colleague):抽象组件代表参与中介者模式的各个组件对象,它们通常具有一个指向中介者的引用,并定义了与其他组件对象通信的接口。

具体组件(ConcreteColleague):具体组件是抽象组件的实现,它们之间通过中介者来通信,而不是直接相互关联。

4 实现步骤

要实现中介者模式,您可以按照以下步骤进行:

定义抽象中介者接口:创建一个抽象中介者接口,其中包括方法来注册和发送消息。

创建具体中介者类:实现抽象中介者接口,管理所有具体组件对象的引用,并协调它们之间的通信。

定义抽象组件接口:创建一个抽象组件接口,其中包括方法来注册中介者和发送消息。

创建具体组件类:实现抽象组件接口,确保它们能够通过中介者对象进行通信。

在具体组件中使用中介者:在具体组件中使用中介者来发送消息,而不是直接与其他组件通信。

客户端代码:在客户端代码中创建中介者和组件对象,然后将组件对象注册到中介者中,以便它们可以相互通信。

5 代码实现

// 1. 定义抽象中介者接口
interface Mediator {
    void register(Colleague colleague);
    void send(String message, Colleague sender);
}

// 2. 创建具体中介者类
class ConcreteMediator implements Mediator {
    private List<Colleague> colleagues = new ArrayList<>();

    @Override
    public void register(Colleague colleague) {
        colleagues.add(colleague);
    }

    @Override
    public void send(String message, Colleague sender) {
        for (Colleague colleague : colleagues) {
            if (colleague != sender) {
                colleague.receive(message);
            }
        }
    }
}

// 3. 定义抽象组件接口
interface Colleague {
    void setMediator(Mediator mediator);
    void send(String message);
    void receive(String message);
}

// 4. 创建具体组件类
class ConcreteColleague implements Colleague {
    private Mediator mediator;
    private String name;

    public ConcreteColleague(String name) {
        this.name = name;
    }

    @Override
    public void setMediator(Mediator mediator) {
        this.mediator = mediator;
    }

    @Override
    public void send(String message) {
        mediator.send(message, this);
    }

    @Override
    public void receive(String message) {
        System.out.println(name + " received: " + message);
    }
}

// 6. 客户端代码
public class Client {
    public static void main(String[] args) {
        Mediator mediator = new ConcreteMediator();

        Colleague colleague1 = new ConcreteColleague("User1");
        Colleague colleague2 = new ConcreteColleague("User2");
        Colleague colleague3 = new ConcreteColleague("User3");

        mediator.register(colleague1);
        mediator.register(colleague2);
        mediator.register(colleague3);

        colleague1.setMediator(mediator);
        colleague2.setMediator(mediator);
        colleague3.setMediator(mediator);

        colleague1.send("Hello, everyone!");
        colleague2.send("Hi there!");
    }
}

6 典型应用场景

中介者模式适用于以下场景:

多对多对象交互:当多个对象之间需要进行复杂的相互通信时,中介者模式可以帮助简化系统结构。

减少耦合性:当对象之间的直接耦合关系导致系统难以维护和扩展时,中介者模式可以降低对象之间的耦合度。

分布式系统:在分布式系统中,各个节点之间可能需要进行协同工作,中介者模式可以用于管理节点之间的通信。

7 优缺点

优点:

降低耦合性:中介者模式将对象之间的通信集中在一个中介者对象中,降低了对象之间的直接耦合,使系统更加灵活。

易于扩展:通过添加新的具体组件和中介者,可以轻松扩展系统,而无需修改现有代码。

集中控制:中介者模式允许将系统的控制逻辑集中在一个对象中,使系统更易于理解和维护。

缺点:

中介者对象复杂:随着系统的增长,中介者对象可能会变得复杂,包含大量的逻辑。

性能问题:由于中介者负责协调对象之间的通信,可能会导致性能问题,特别是在大规模系统中。

8 类似模式

与中介者模式类似的模式包括观察者模式和代理模式。虽然它们在某些方面具有相似性,但它们在用途和实现方式上有一些关键区别。

观察者模式(Observer Pattern):

观察者模式和中介者模式都处理对象之间的通信,但它们关注的侧重点不同。观察者模式是一对多的关系,其中一个主题对象(Subject)维护一组观察者(Observer),当主题对象的状态发生变化时,通知所有观察者。观察者之间通常不直接通信,而是通过主题对象。中介者模式关注多对多的对象通信,中介者充当对象之间的中心枢纽,协调它们的交互。观察者模式关注一对多的依赖关系,其中主题对象维护观察者列表,但观察者之间不直接通信,而是通过主题对象。

代理模式(Proxy Pattern):

代理模式和中介者模式都涉及到控制对象之间的访问和交互。代理充当目标对象的代表,可以控制对目标对象的访问。中介者模式关注多个对象之间的通信和协调,它引入一个中介者对象,使对象之间的关系更加松散。代理模式关注对单个对象的访问控制,代理对象通常封装了目标对象的功能,但并不协调多个对象之间的交互。

虽然这些模式都有助于降低对象之间的耦合性,但它们的关注点和应用场景略有不同。中介者模式用于协调多个对象之间的复杂通信,观察者模式用于建立一对多的依赖关系,代理模式用于控制对单个对象的访问,而发布-订阅模式用于发布和订阅事件或消息。选择哪种模式取决于具体的设计需求和问题背景。

9 小结

中介者模式是一种有助于管理多个对象之间通信的强大工具。通过引入中介者对象,它能够降低对象之间的耦合度,使系统更加灵活、易于扩展和维护。在设计软件系统时,考虑使用中介者模式来促进对象之间的松耦合关系,提高系统的可维护性和可扩展性。

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

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

相关文章

如何配置代理

打开Clask&#xff0c;设置为系统代理&#xff0c;选择规则判断&#xff0c;规则判断就是需要走代理的走代理&#xff0c;不需要走的就不用走代理 本地使用代理 如何想要让某个地方使用代理&#xff0c;可以直接在该地方的终端进行设置 先复制一下终端代理命令&#xff0c;然…

python使用mitmproxy和mitmdump抓包在手机上抓包(三)

现在手机的使用率远超过电脑&#xff0c;所以这篇记录用mitmproxy抓手机包&#xff0c;实现手机流量监控。 环境&#xff1a;win10 64位&#xff0c;Python 3.10.4&#xff0c;雷电模拟器4.0.78&#xff0c;android版本7.1.2&#xff08;设置-拉至最底部-关于平板电脑&#xf…

一篇博客学会系列(2)—— C语言中的自定义类型 :结构体、位段、枚举、联合体

目录 前言 1、结构体 1.1、结构体类型的声明 1.2、特殊的结构体类型声明 1.3、结构体的自引用 1.4、结构体的定义和初始化 1.5、结构体成员变量的调用 1.6、结构体内存对齐 1.6.1、offsetof 1.6.2、结构体大小的计算 1.6.3、为什么存在内存对齐&#xff1f; 1.7、…

C理解(一):内存与位操作

本文主要探讨C语言的内存和为操作操作相关知识。 冯诺依曼结构和哈佛结构 冯诺依曼结构&#xff1a;数据和代码放在一起,便于读取和修改,安全性低 哈佛结构是&#xff1a;数据和代码分开存放,安全性高,读取和修麻烦 内存 内存是用来存储全局变量、局…

chatgpt,神经网络与拥塞控制

chatgpt 是一个巨大的带答案的完形填空题库&#xff0c;它可以回答几乎所有的文字类问题&#xff0c;不保证完全正确&#xff0c;但大致正确。它是怎么做到的&#xff1f; 它怎么知道我要问什么&#xff0c;如果它知道我要问什么&#xff0c;那么问题的不同表达形式它也一定知…

如何利用AI算法+EasyCVR视频监控技术打造鱼塘养殖监管方案

对鱼塘养殖行业来说&#xff0c;养殖区域面积大、管理难&#xff0c;经常会遇到偷钓者、盗窃鱼苗、非法入侵等监管难题。传统的人工监管模式不仅耗费人力成本&#xff0c;而且监管效率低下&#xff0c;无法满足当前养殖户的需求。因此&#xff0c;搭建智能化的远程视频监控系统…

Linux 基本语句_5_创建静态库|动态库

静态库 创建主函数&#xff1a;main.c 应用函数&#xff1a;add.c、sub.c、mul.c 创建calc.h文件作为头文件 生成可执行文件*.o文件 gcc -c add.c -o add.o ....包装*.o文件为静态库 ar -rc libmymath.a add.o sub.o mul.o编译静态库并指明创建静态库的位置 sudo gcc mai…

原型、原型链、判断数据类型

目录 作用 原型链 引用类型&#xff1a;__proto__(隐式原型)属性&#xff0c;属性值是对象函数&#xff1a;prototype(原型)属性&#xff0c;属性值是对象 Function&#xff1a;本身也是函数 相关方法 person.prototype.isPrototypeOf(stu) Object.getPrototypeOf(objec…

论企业IPV4和IPV6网络融合互通网络规划设计

01、IPv6改造问题及整体改造思路 随着“十四五”期间国家政策对IPv6深化改造及规模部署的推动&#xff0c;在IPv6改造过程中出现了越来越多的系统性问题&#xff0c;如图1所示。 图1 关于IPv6改造的各种疑问 所有跨设备通信的IT软硬件系统均需要处理IP地址&#xff0c;各领域…

Android SDK目录结构

目录结构如下&#xff1a; 1&#xff1a;add-ons 该目录中存放 Android 的扩展库&#xff0c;比如 Google Maps&#xff0c;但若未选择安装 Google API&#xff0c;则该目录为空。 2&#xff1a;build-tools 编译工具目录&#xff1a;保存了Android开发常用的工具&#xff0…

【.NET源码解读】Configuration组件及自动更新

Configuration组件是.NET中一个核心的、非常重要的组件。它提供了一种方便的机制&#xff0c;用于从配置文件、环境变量、命令行参数等各种数据源中读取和配置应用程序&#xff0c;以满足不同环境下应用程序的需求。 在本篇文章中&#xff0c;将会介绍Configuration的基本用法…

使用Visual Studio调试排查Windows系统程序audiodg.exe频繁弹出报错

VC常用功能开发汇总&#xff08;专栏文章列表&#xff0c;欢迎订阅&#xff0c;持续更新...&#xff09;https://blog.csdn.net/chenlycly/article/details/124272585C软件异常排查从入门到精通系列教程&#xff08;专栏文章列表&#xff0c;欢迎订阅&#xff0c;持续更新...&a…

智慧燃气平台的总体架构到底应怎样设计?

关键词&#xff1a;智慧燃气、智慧燃气平台、智能燃气、智能监控 智慧燃气平台功能设计的一些方向和思考&#xff1a; 1、资源统一&#xff0c;管理调度 城市燃气智慧调度运营管理平台收集并且整理出每个业务系统信息&#xff0c;并且根据所整理出的信息结果制定出标准规范&…

Excel·VBA分列、字符串拆分

看到一篇博客《VBA&#xff0c;用VBA进行分列&#xff08;拆分列&#xff09;的2种方法》&#xff0c;使用VBA对字符串进行拆分 目录 Excel分列功能将字符串拆分为二维数组&#xff0c;Split函数举例 将字符串拆分为一维数组&#xff0c;正则表达式举例 Excel分列功能 Sub 测…

windows下使用VS2019 + CMake 进行Qt开发记录

windows下使用VS2019 CMake 进行Qt开发 前言一、准备工作二、VS2019 cmake3.20 Qt1.VS2019新建一个cmake工程2.修改CMakelist.txt3.运行测试 总结 前言 注意&#xff1a;本文讲的是vs2019 cmake的方式开发Qt程序。 常言道&#xff1a;工欲善其事必先利其器。工具利用的好…

数字货币的一些隐私保护问题

常见的数字货币基本模型 代表数字货币的不同架构和交易验证方式。 Account Based 基于账户的数字货币模型。主要特点 账户地址&#xff1a;每个用户都有一个唯一的账户地址&#xff0c;类似于银行账户号码。这个地址用来标识用户的身份&#xff0c;并用于接收、存储和发送…

多线程学习(C/C++)

1.进程 运行着的程序就是进程 进程的特性:1.独立性 2.动态性 3.并发性 (1)进程的状态 进程一共有五种状态分别为:创建态,就绪态,运行态,阻塞态(挂起态),退出态(终止态)其中创建态和退出态维持的时间是非常短的,稍纵即逝。我们主要是需要将就绪态, 运行态, 挂起态,三者…

7.网络原理之TCP_IP(上)

文章目录 1.网络基础1.1认识IP地址1.2子网掩码1.3认识MAC地址1.4一跳一跳的网络数据传输1.5总结IP地址和MAC地址1.6网络设备及相关技术1.6.1集线器&#xff1a;转发所有端口1.6.2交换机&#xff1a;MAC地址转换表转发对应端口1.6.3主机&#xff1a;网络分层从上到下封装1.6.4主…

文件的编译与链接

目录 翻译环境与链接环境&#xff1a; 翻译环境&#xff1a; 编译器部分&#xff1a; 预处理&#xff1a; 编译&#xff1a; 词法分析&#xff1a; 语法分析&#xff1a; 语义分析&#xff1a; 汇编&#xff1a; 小总结&#xff1a; 链接器部分&#xff1a; 运行环境…

LLMS: 将模型与人类价值观对齐Aligning models with human values

欢迎回来。让我们回到 生成式 AI 项目的生命周期。 上周&#xff0c;你 仔细研究了一种叫做微调的技术。 使用 指令&#xff08;包括路径方法&#xff09;进行微调的目标是 进一步训练 模型&#xff0c;以便它们更好地理解 类似人类的提示并 生成更多类似人类的响应。 与基…