设计模式——中介者模式(Mediator)

中介者模式(Mediator Pattern)是一种行为型设计模式,其主要作用是通过一个中介对象来封装一系列对象的交互,从而降低它们之间的耦合度,提高系统的可维护性和可扩展性。

中介者模式的主要特点

  • 封装交互:用一个中介对象来封装一系列对象的交互,这些对象不再直接相互引用,而是通过中介者进行交互。
  • 降低耦合:由于对象之间的交互被封装在中介者对象中,因此它们之间的耦合度降低,对象可以更加独立地变化和复用。
  • 集中控制:多个对象之间的交互被封装在中介者对象中集中管理,当交互行为发生变化时,只需要修改中介者对象即可,而不需要修改各个对象。
  • 一对多关联:通过引入中介者对象,将原本多个对象之间复杂的多对多关联关系转变为对象与中介者之间的一对多关联关系,简化了系统的结构。

中介者模式的角色

  • 中介者(Mediator):定义了一个接口,用于与各同事对象进行通信。
  • 同事对象(Colleague):实现了一个接口,该接口用于与中介者进行通信。同事对象之间不再直接相互引用,而是通过中介者进行交互。

中介者模式的优缺点

优点

  • 降低了对象之间的耦合度,使得对象更加独立,易于复用和维护。
  • 将对象间复杂的多对多关联关系转变为简单的一对多关联关系,提高了系统的灵活性和可扩展性。
  • 集中控制交互行为,使得修改和维护更加容易。

缺点

  • 当同事对象数量较多时,中介者对象可能会变得臃肿和复杂,难以维护。
  • 如果中介者对象出现故障,可能会导致整个系统崩溃。

适用场景

  • 当系统中对象之间存在复杂的引用关系,导致系统结构混乱且难以理解时。
  • 当需要创建一个运行于多个类之间的对象,但又不想生成新的子类时。
  • 当需要改变系统的交互方式,但又不希望修改现有的对象时。

示例

我们可以考虑一个简单的聊天室示例,其中用户(同事对象)通过聊天室(中介者)进行通信。以下是这个示例的Java代码:

// 同事接口
interface Colleague {
    void sendMessage(String message);
    void receiveMessage(String message);
    void setMediator(Mediator mediator);
}

// 用户类,实现同事接口
class User implements Colleague {
    private Mediator mediator;
    private String name;

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

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

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

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

// 中介者接口
interface Mediator {
    void register(Colleague colleague);
    void sendMessage(Colleague sender, String message);
}

// 聊天室类,实现中介者接口
class ChatRoom implements Mediator {
    private List<Colleague> colleagues = new ArrayList<>();

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

    @Override
    public void sendMessage(Colleague sender, String message) {
        for (Colleague colleague : colleagues) {
            if (!colleague.equals(sender)) {
                colleague.receiveMessage(sender.name + ": " + message);
            }
        }
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        ChatRoom chatRoom = new ChatRoom();

        User user1 = new User("Alice");
        User user2 = new User("Bob");

        chatRoom.register(user1);
        chatRoom.register(user2);

        user1.sendMessage("Hello, Bob! How are you?");
    }
}

在这个示例中,我们定义了一个Colleague接口,它包含了发送和接收消息的方法以及设置中介者的方法。User类实现了这个接口,并包含了用户的名字。Mediator接口定义了注册同事和发送消息的方法。ChatRoom类实现了这个接口,并管理了一个同事对象的列表。在ChatRoomsendMessage方法中,它遍历了所有的同事对象,并将消息发送给除了发送者之外的所有其他同事。

Client类中,我们创建了一个ChatRoom对象和两个User对象,并将它们注册到聊天室中。然后,我们让Alice向Bob发送一条消息。当这条消息被发送时,聊天室会将它转发给所有其他的用户(在这个例子中只有Bob),并打印出接收到的消息。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

java中的oop(一)、概念

一、三大主线 &#xff08;非官方&#xff09; 成员&#xff1a;属性、方法、构造器、&#xff08;代码块&#xff0c;内部类&#xff09;&#xff1b; 特征&#xff1a;封装、继承、多态、&#xff08;抽象&#xff09;——三大特征&#xff1b; 关键字&#xff1a; this、…

Cmake编译源代码生成库文件以及使用

在项目实战中&#xff0c;通过模块化设计能够使整个工程更加简洁明了。简单的示例如下&#xff1a; 1、项目结构 project_folder/├── CMakeLists.txt├── src/│ ├── my_library.cpp│ └── my_library.h└── app/└── main.cpp2、CMakeList文件 # CMake …

Spark云计算平台Databricks使用,第一个Spark应用程序WordCount

1 上传文件 上传words.txt文件&#xff1a;Spark云计算平台Databricks使用&#xff0c;上传文件-CSDN博客 上传的文件的路径是/FileStore/tables/words.txt&#xff0c;保存在AWS的S3 hello world hello hadoop hello world hello databricks hadoop hive hbase yarn spark …

金蝶BI应收分析报表:关于应收,这样分析

这是一张出自奥威-金蝶BI方案的BI应收分析报表&#xff0c;是一张综合运用了筛选、内存计算等智能分析功能以及数据可视化图表打造而成的BI数据可视化分析报表&#xff0c;可以让企业运用决策层快速知道应收账款有多少&#xff1f;账龄如何&#xff1f;周转情况如何&#xff1f…

5.9号模拟前端面试10问

5.9号模拟前端面试10问 1.html语义化的理解 HTML语义化是指使用具有明确含义的HTML标签来描述内容&#xff0c;而不仅仅是使用<div>和<span>等通用容器标签。语义化的HTML代码更易于阅读和维护&#xff0c;同时也有助于搜索引擎优化&#xff08;SEO&#xff09;。…

前端基础知识-ES6扩展运算符(快速实现数组添加新元素、字符串转为数组、对象添加新属性)

前言&#xff1a; 扩展运算符又称为Rest运算符&#xff0c;可以实现数组、对象、字符串在语法层面上的展开&#xff0c;达到简化语法的目的&#xff0c;使得我们提高开发效率 主要用法&#xff1a; 在需要解构的变量前加三个点&#xff08;...xxx&#xff09; 具体示例&…

大数据毕业设计Python+Django地铁客流量预测 时间序列 深度学习 机器学习 人工智能 Python爬虫 计算机毕业设计

​ 博主介绍&#xff1a;全网粉丝100W,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业毕业设计项目实战6年之久&#xff0c;选择我们就是选择放心、选择安心毕业感兴趣的可以先收藏起来&#xff0c;点赞、关注不迷路 西安工程大学本科毕业设计&#xff…

Xamarin.Android项目网络串口助手怎么通过路由器跟PC网络串口连接

AndroidManifest.xml ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/1ae7cd0d03c84343a62bccfd92e45d2c.png)

Mendix创客访谈录|助力工业领域,Mendix与IIOT相融合

本期创客 汤登揆 太平洋电信股份有限公司 AI 技术支持工程师 大家好&#xff0c;我是汤登揆&#xff0c;帝国理工大学&#xff0c;生态算法专业&#xff0c;主要关注于产品结构分析和产品应用落地。 目前任职于太平洋电信股份有限公司&#xff0c;主要专注于AI大模型的应用落地…

python3.12.0 在Linux 制作镜像包 部署到docker 全过程

项目结构&#xff1a; 比如&#xff0c;在pycharm里需要运行 themain.py 1、上传Linux的目录结构&#xff1a; Dockerfile 文件需要制作&#xff1a; 这里是关键&#xff1a; #基于的基础镜像 FROM python:3.12.0 #代码添加到code文件夹 ADD ./EF_NFCS /code #设置code文…

工厂的隐性成本有哪些?如何应对?

隐性成本是指企业在生产过程中不易被察觉或量化的成本&#xff0c;它们往往隐藏在企业的日常运营中&#xff0c;但同样会对企业的总成本产生影响。 工厂的隐性成本有哪些&#xff1f; 工厂的隐性成本主要包括以下几个方面&#xff1a; 1、停滞资源成本&#xff1a;如闲置的机…

effective python学习笔记_推导与生成

用推导取代map和filter 序列推导可取代map和filter&#xff0c;优越性有&#xff1a;1可读性强2不需要map的函数 控制推导逻辑的子表达式不要超过2个 即推导的for层数最多建议两层&#xff0c;多了可读性会下降&#xff0c;反而用for循环会清晰 一层for内可连接多个if&…

LifeCycle之ProcessLifeCycleOwner

问题&#xff1a;想要知道应用程序当前处在前台、后台、或从后台回到前台&#xff0c;想要知道应用的状态&#xff0c; LifeCycle提供了ProcessLifeCycleOwner的类&#xff0c;方便我们知道整个应用程序的生命周期情况 ProcessLifeCycleOwner 使用方法 1.首先添加依赖 imple…

初学者理解Transformer,本文is all you need

要问现在AI领域哪个概念最热&#xff0c;必然是openAI推出chatGPT之后引发的大模型。然而这项技术的起源&#xff0c;都来自一篇google公司员工的神作“Attention Is All You Need”——本文标题也是一种致敬^_^&#xff0c;目前已有近12万的引用(还在增长)。 在“Attention Is…

【qt】容器的用法

容器目录 一.QVertor1.应用场景2.增加数据3.删除数据4.修改数据5.查询数据6.是否包含7.数据个数8.交换数据9.移动数据10.嵌套使用 二.QList1.应用场景2.QStringList 三.QLinkedList1.应用场景2.特殊点3.用迭代器来变量 四.QStack1.应用场景2.基本用法 五.QQueue1.应用场景2.基本…

【设计模式】JAVA Design Patterns——Abstract-document

&#x1f50d; 目的 使用动态属性&#xff0c;并在保持类型安全的同时实现非类型化语言的灵活性。 &#x1f50d; 解释 抽象文档模式使您能够处理其他非静态属性。 此模式使用特征的概念来实现类型安全&#xff0c;并将不同类的属性分离为一组接口 真实世界例子 考虑由多个部…

【Linux】在Linux中执行命令ifconfig, 报错-bash:ifconfig: command not found解决方案

一、报错信息 ifconfig 报错-bash:ifconfig: command not found 同时&#xff0c;通过ip addr查看&#xff0c;也看不到IP信息 二、解决方案 找到ifcfg-ens0文件&#xff0c;此文件的目录在/etc/sysconfig/network-scripts目录下 命令&#xff1a;cd /etc/sysconfig/network…

89C52单片机+ESP8266做的物联网+反馈 e4a手机客户端源程序

资料下载地址&#xff1a;89C52单片机ESP8266做的物联网反馈 e4a手机客户端源程序 MCU是89C52单片机 WiFi模块是ESP8266 其他 8路继电器 电源模块 使用贝壳物联做服务器 还有客户端。 也可以用花生壳做内网穿透&#xff0c;8266做服务器&#xff0c;也可以实现物联以及反馈&a…

vue多选功能

废话不多说&#xff0c;直接上代码&#xff01;&#xff01;&#xff01; <template><div class"duo-xuan-page"><liv-for"(item, index) in list":key"index"click"toggleSelection(item)":class"{ active: sel…

[前后端基础]图片详解

[前后端基础]图片传输与异步-CSDN博客 https://juejin.cn/post/6844903782959022093#heading-3 base64、file和blob用JS进行互转的方法大全【前端】_js base64转blob-CSDN博客 后端存储方式 对于第一种存储方式&#xff0c;我们前端直接将存储路径赋值给 src 属性即可轻松显示。…
最新文章