设计模式16、中介者模式 Mediator

news2024/11/16 10:55:51
解释说明:中介者模式(Mediator Pattern)用一个中介对象来封装一系列的对象交互
中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
抽象中介者(Mediator):为 Colleague 对象之间的通信定义接口。
具体中介者(ConcreteMediator):实现 Mediator 接口,并需要了解和维护各个 Colleague 对象,负责协调他们之间的通信。
抽象同事类(Colleague):定义与其他 Colleague 通信的接口。
具体同事类 (ConcreteColleague):实现 Colleague 接口,并通过 Mediator 与其他 Colleague 进行沟通。
中介者是对象的通信中心。当一个对象需要与另一个对象通信时,它不会直接调用另一个对象。相反,它会调用中介者对象,其主要职责是将消息路由到目标对象。它允许开发人员不必管理对象之间的链接。
优点:
    中介者模式简化了对象之间的交互,它用中介者和同事的一对多交互代替了原来同事之间的多对多交互,一对多关系更容易理解、维护和扩展,将原本难以理解的网状结构转换成相对简单的星型结构。
    中介者模式可将各同事对象解耦。中介者有利于各同事之间的松耦合,可以独立地改变和复用每一个同事和中介者,增加新的中介者和新的同事类都比较方便,更好地符合“开闭原则”。
    可以减少子类生成,中介者将原本分布于多个对象间的行为集中在一起,改变这些行为只需生成新的中介者子类即可,这使各个同事类可被重用,无须对同事类进行扩展。
缺点:
    如果存在大量同事之间的交互,中介者将会变得非常复杂,使得系统难以维护。
适用场景
    系统中对象之间存在比较复杂的引用关系,导致它们之间的依赖关系结构混乱而且难以复用该对象。
    想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。
mediator.h
#pragma once
#include "colleague.h"
#include <list>
#include <string>
class IColleague;
// 抽象中介者
class IMediator
{
public:
       // 注册参与者
       virtual void registerColleague(IColleague* colleague)
       {
              m_colleagues.emplace_back(colleague);
       }
       const std::list<IColleague*>& getColleagues() const
       {
              return m_colleagues;
       }
       // 将发送者的消息发送给所有参与者
       virtual void distributeMessage(const IColleague* sender, const std::string& message) const = 0;
private:
       std::list<IColleague*> m_colleagues;
};
concreteMediator.h
#pragma once
#include "mediator.h"
// 具体中介者
class ConcreteMediator : public IMediator
{
public:
       // 将发送者的消息发送给所有参与者(但不包括发送者自己)
       virtual void distributeMessage(const IColleague* sender, const std::string& message) const override
       {
              for (const IColleague* c : getColleagues())
                     if (c != sender)  // 不要将消息发送给自己
                           c->receiveMessage(sender, message);
       }
};
colleague.h
#pragma once
#include "mediator.h"
#include <string>
class IMediator;
// 抽象同事类
class IColleague
{
public:
       IColleague(const std::string& name) : m_strName(name) {}
       std::string getName() const { return m_strName; }
       // 通过中介者,将自己的消息发布出去
       virtual void sendMessage(const IMediator& mediator, const std::string& message) const = 0;
       // 接收来自发送者的消息
       virtual void receiveMessage(const IColleague* sender, const std::string& message) const = 0;
private:
       std::string m_strName;
};
concreteColleague.h
#pragma once
#include "colleague.h"
#include <iostream>
// 具体同事类
class ConcreteColleague : public IColleague
{
public:
       using IColleague::IColleague;
       // 通过中介者,将自己的消息发布出去
       virtual void sendMessage(const IMediator& mediator, const std::string& message) const override
       {
              mediator.distributeMessage(this, message);
       }
private:
       // 接收来自发送者的消息
       virtual void receiveMessage(const IColleague* sender, const std::string& message) const override
       {
              std::cout << getName() << " received the message from "
                     << sender->getName() << ": " << message << std::endl;
       }
};
main.cpp
#include "concreteColleague.h"
#include "concreteMediator.h"
#ifndef SAFE_DELETE
#define SAFE_DELETE(p) { if(p){delete(p); (p)=NULL;} }
#endif
int main()
{
       // 房东
       IColleague* landlord = new ConcreteColleague("Tom");
       // 租客
       IColleague* jerry = new ConcreteColleague("Jerry");
       IColleague* tuffy = new ConcreteColleague("Tuffy");
       // 中介者 - 添加租客
       ConcreteMediator mediator;
       mediator.registerColleague(jerry);
       mediator.registerColleague(tuffy);
       // 房东通过中介将消息发送出去
       landlord->sendMessage(mediator, "Xi'erqi, two bedroom house, 6000/month.");
       SAFE_DELETE(jerry);
       SAFE_DELETE(tuffy);
       system("pause");
       return 0;
}

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

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

相关文章

Kaadas凯迪仕助力亚运盛会,尽展品牌硬核科技与智能锁行业风采

9月23日至10月8日&#xff0c;亚洲最大规模体育赛事亚运会在杭州举办。作为国际性体育赛事&#xff0c;除赛中的各类竞赛项目外&#xff0c;杭州亚运会前后相关活动也吸引了大众目光的聚焦。 Kaadas凯迪仕智能锁作为此次杭州亚运会官方指定智能门锁&#xff0c;以#凯迪仕守护每…

IP真人识别方法与代理IP检测技术

随着互联网的发展&#xff0c;IP地址在网络安全和数据分析中扮演着重要的角色。为了维护网络的安全性和识别真实用户&#xff0c;IP地址的真实性和来源成为了一个关键问题。 什么是IP真人识别&#xff1f; IP真人识别是一种技术&#xff0c;旨在确定IP地址背后的用户是否为真实…

深入理解RBAC

RBAC是一种基于角色实现访问控制的权限管理机制&#xff0c;通过定义角色和权限、用户和角色、角色和角色之间的关系&#xff0c;实现多层次、细粒度、可复用的权限管理系统。原文: Role-based Access Control (RBAC) Model[1] Bernard HermantUnsplash Avery Pennarun写的&quo…

XML文件详解 (java程序解析XML文件,java程序写XML文件)

XML 的全称是可扩展标记语言&#xff08;eXtensible Markup Language&#xff09; xml本质上是一种数据的格式&#xff0c;可以用来存储复杂的数据结构和数据关系。 使用XML&#xff08;可扩展标记语言&#xff09;有以下几个好处&#xff1a; 可读性强&#xff1a;XML使用标…

微信小程序 获取当前屏幕的可见高宽度

很多时候我们做一下逻辑 需要用整个窗口的高度或宽度参与计算 而且很多时候我们js中拿到的单位都是px像素点 没办法和rpx同流合污 官方提供了wx.getSystemInfoSync() 可以获取到部分窗口信息 其中就包括了整个窗口的宽度和高度 wx.getSystemInfoSync().windowHeight 返回值为像…

ElasticSearch 安装,保存,查询,更新,复杂查询,模糊查询,高亮查询

ElasticSearch ik分词器&#xff1a; ik分词器的安装&#xff0c;将ik分词器下载并解压&#xff0c;新建文件夹ik&#xff0c;将解压内容放进ik文件夹中&#xff0c;将ik文件夹放在es安装路径的plugin文件夹中 GET _analyze {"analyzer": "ik_smart",&q…

C++对string进行大小写转换的三种方法

C对string进行大小写转换的三种方法 方法一&#xff1a;下标 #include <iostream> #include <string> using namespace std;int main() {string s "ABCDEFG";for( int i 0; i < s.size(); i ){s[i] tolower(s[i]);}cout<<s<<endl;re…

详细解说iptables 高阶用法,用来完成哪些高效率网络路由策略场景,iptables 实现域名过滤,Linux如何利用iptables屏蔽某些域名?

详细解说iptables 高阶用法,用来完成哪些高效率网络路由策略场景,iptables 实现域名过滤,Linux如何利用iptables屏蔽某些域名? Linux利用iptables屏蔽某些域名 以下规则是屏蔽以 youtube.com 为主的所有一级 二级 三级等域名。 iptables -A OUTPUT -m string --string &qu…

XLSX.utils.sheet_to_json()解析excel,给空的单元格赋值为空字符串

前言 今天用到XLSX来解析excel文件&#xff0c;调用XLSX.utils.sheet_to_json(worksheet)&#xff0c;发现如果单元格为空的话&#xff0c;解析出来的结果&#xff0c;就会缺少相应的key&#xff08;如图所示&#xff09;。但是我想要单元格为空的话&#xff0c;值就默认给空字…

layui tree监控选中事件,同步选中和取消

需求&#xff1a;需要分配权限时&#xff0c;要通过组织架构分配&#xff0c;也要通过角色分配&#xff0c;还是把选择的结果显示出来 结果如下图 代码分页面&#xff0c;类和SQL 页面&#xff1a; <% Page Language"C#" AutoEventWireup"true" Code…

ElasticSearch搜索引擎: 内存分析与设置

在 Elasticsearch 的运行过程中&#xff0c;如何合理分配与设置内存是一件十分重要的事情&#xff0c;否则十分容易出现各种问题。 一、Elasticsearch为什么吃内存&#xff1a; 我们先看下 ES 服务器的总体内存消耗情况&#xff1a; 对于Query Cache、Request Cache、Field…

IT和OT 之间的教育鸿沟

自动化行业正在大力倡导开放自动化系统&#xff0c;使更多IT技术能够导入传统的自动控制行业。并且提出让开放自动化系统消除IT和OT 之间的鸿沟。笔者看来&#xff0c;IT和OT 之间除了技术上的鸿沟之外&#xff0c;还存在着人才鸿沟。近年来&#xff0c;面向智能制造行业的软件…

生物制药公司【Lexeo Therapeutics】申请1亿美元纳斯达克IPO上市

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 猛兽财经获悉&#xff0c;生物制药公司【Lexeo Therapeutics】近期已向美国证券交易委员会&#xff08;SEC&#xff09;提交招股书&#xff0c;申请在纳斯达克IPO上市&#xff0c;股票代码为(LXEO),Lexeo Therapeutics计划…

万万没想到有一天居然可以在 Mac 上玩游戏,而且还是原神!

万万没想到有一天居然可以在 Mac 上玩游戏&#xff0c;而且还是原神&#xff0c;我真的哭死~ 是这样的&#xff0c;我以前一直用 Mac 来办公也没想过要打游戏&#xff0c;在我心中 Mac 就是用来办公的&#xff0c;生产力工具&#xff0c;直到有一天我刷到一个视频&#xff0c;…

开发餐饮类私域流量是开发应用APP还是小程序还是低代码跨平台APP分析他的利与弊

在开发餐饮类应用程序时&#xff0c;我们需要先了解市场需求&#xff0c;定义目标受众&#xff0c;并提供独特的功能。个人感觉我们提供周围的在线订购、外卖服务、用户评价等功能&#xff0c;以吸引用户。同时&#xff0c;设计用户习惯的界面&#xff0c;使用户轻松选择自己的…

Qt绘图系统

文章目录 一.Qt绘图系统简介二.支持绘图系统的类三.绘图后端四.绘图和填充绘图填充Qt::BrushStyle 五.坐标系系统 一.Qt绘图系统简介 Qt的绘画系统支持使用相同的API在屏幕和打印设备上进行绘画&#xff0c;并且主要基于QPainter、QPaintDevice和QPaintEngine类。这种方法的主…

充电100%并非都是美事,有时少点更有溢出!如何正确为iPhone充电

iPhone是非凡的设备&#xff0c;但一旦电池耗尽&#xff0c;它们就会失去光泽。这就是为什么照看电池内部并确保始终正确充电很重要。 在这篇文章中&#xff0c;我们解释了如果你想让你的iPhone每天运行到深夜&#xff0c;并尽可能多地保持这种状态&#xff0c;你需要采取的步…

灰豚数字人平台AI创作助手,一键成片简化短视频制作过程,创作量突破百万!

国内AI语言大模型越来越多&#xff0c;人工智能已经全面进入我们的日常生活。其中&#xff0c;灰豚AI数字人平台的AI一键成片技术以其特独优势必&#xff0c;越来越受到短视频创作的青睐。本文将详细介绍灰豚AI数字人平台的应用场景以未来的发展前景。 灰豚数字人官网 一、灰豚…

Vue中使用Echarts封装为公用组件(简单复制粘贴)

Vue中封装Echarts组件 前提直奔主题 本文以Vue3代码演示 Vue2同理 前提 中文官网&#xff1a; https://echarts.apache.org/zh/index.html npm安装Echarts npm install echarts or pnpm install echarts or yarn add echarts直奔主题 创建Echarts.vue文件&#xff0c;代码如…

【Java每日一题】— —第二十六题:编程定义一个经理类Manager。(2023.10.10)

&#x1f383;个人专栏&#xff1a; &#x1f42c; 算法设计与分析&#xff1a;算法设计与分析_IT闫的博客-CSDN博客 &#x1f433;Java基础&#xff1a;Java基础_IT闫的博客-CSDN博客 &#x1f40b;c语言&#xff1a;c语言_IT闫的博客-CSDN博客 &#x1f41f;MySQL&#xff1a…