c++如何实现中介者模式 c++设计模式之Mediator【实例】


中介者模式通过引入中介者对象解耦多个对象间的直接交互。其核心角色包括抽象中介者、具体中介者、抽象同事类和具体同事类,C++中需用指针避免循环引用,典型应用如聊天室或UI控件联动。

中介者模式(Mediator Pattern)的核心是解耦多个对象之间的直接交互,把它们的通信集中到一个中介者对象中统一处理。在 C++ 中,通过定义抽象中介者、具体中介者、抽象同事类和具体同事类,就能清晰实现这一结构。

关键角色与类设计

需要四个基本组成部分:

  • Mediator(抽象中介者):声明同事间通信的接口,通常为纯虚函数,如 notify(Colleague*, std::string event)
  • ConcreteMediator(具体中介者):持有所有同事对象的引用或指针,实现具体协调逻辑,决定事件发生时谁该响应、如何响应
  • Colleague(抽象同事类):保存对中介者的弱引用(如 Mediator*),不直接依赖其他同事,只通过中介者通信
  • ConcreteColleague(具体同事类):继承 Colleague,触发事件时调用 mediator->notify(this, "event"),接收通知时重写响应逻辑

完整可运行示例(控制台聊天室)

模拟两个用户(UserA 和 UserB)通过 ChatRoom(中介者)发送消息:

#include 
#include 
#include 

class Mediator; class Colleague { protected: Mediator mediator_; public: explicit Colleague(Mediator m) : mediator_(m) {} virtual void send(const std::string& msg) = 0; virtual void receive(const std::string& msg) = 0; };

class Mediator { public: virtual void notify(Colleague* sender, const std::string& msg) = 0; };

class ChatRoom : public Mediator { std::vector participants_;

public: void registerParticipant(Colleague& c) { participants_.push_back(&c); }

void notify(Colleague* sender, const std::string& msg) override {
    for (auto* p : participants_) {
        if (p != sender) { // 不发给自己
            p-youjiankuohaophpcnreceive("[ChatRoom] " + std::string(sender-youjiankuohaophpcnname()) + ": " + msg);
        }
    }
}

};

class User : public Colleague { std::string name_;

public: User(const std::string& n, Mediator* m) : Colleague(m), name_(n) {}

const char* name() const { return name_.c_str(); }

void send(const std::string& msg) override {
    mediator_-youjiankuohaophpcnnotify(this, msg);
}

void receive(const std::string& msg) override {
    std::cout zuojiankuohaophpcnzuojiankuohaophpcn name_ zuojiankuohaophpcnzuojiankuohaophpcn " received: " zuojiankuohaophpcnzuojiankuohaophpcn msg zuojiankuohaophpcnzuojiankuohaophpcn "\n";
}

};

int main() { ChatRoom room; User alice("Alice", &room); User bob("Bob", &room);

room.registerParticipant(alice);
room.registerParticipant(bob);

alice.send("Hi Bob!");
bob.send("Hello Alice!");

return 0;

}

使用要点与注意事项

实际项目中需注意以下细节:

  • 中介者应尽量保持“无知”——不暴露同事内部状态,只传递必要事件名或数据包,避免强耦合
  • 同事类中建议用 Mediator* 而非 std::shared_ptr,防止循环引用;若需生命周期绑定,可用 std::weak_ptr
  • 复杂系统中可扩展为事件总线(Event Bus):用字符串/枚举标识事件类型,支持订阅-发布机制
  • UI 场景常见应用:窗口中多个控件(按钮、文本框、下拉框)联动时,用一个 DialogMediator 统一处理变更响应,而非让按钮直接操作文本框

何时选用中介者模式

适合以下典型场景:

  • 一组对象以定义良好但复杂的方式进行通信,导致相互依赖关系网状化、难以复用
  • 想定制一个分布在多个类中的行为,又不想生成大量子类(相比观察者,中介者更强调“协调决策”)
  • 需要在不修改现有类的前提下,动态改变对象间的交互逻辑(只需替换 ConcreteMediator 实现)


# ai  # c++  # ios  # stream  # red  # String  # 子类  # const  # 字符串  # int  # 循环  # 指针  # 继承  # 虚函数  # 纯虚函数  # 接口  # class  # public  # Event  # 对象  # 事件  # this  # ui  # 多个  # 而非  # 文本框  # 类中  # 聊天室  # 中统  # 这一  # 就能  # 只需 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 网络优化76771 】 【 技术知识130152 】 【 IDC云计算60162 】 【 营销推广131313 】 【 AI优化88182 】 【 百度推广37138 】 【 网站推荐60173 】 【 精选阅读31334


相关推荐: Python变量绑定机制_引用模型解析【教程】  如何使用Golang处理静态文件缓存_提高页面加载速度  php高频调试功能有哪些_php常用调试函数与工具汇总【解答】  c++协程和线程的区别 c++异步编程模型对比【核心】  Win11怎么开启游戏模式_Win11优化游戏帧数性能【教程】  如何在 Go 中正确反序列化多个同级 XML 元素(而非单个根节点)  Win11怎么关闭自动调节亮度 Win11禁用内容自适应亮度【设置】  LINUX怎么进行文本内容搜索_Linux grep命令正则表达式用法大全【教程】  php删除数据怎么软删除_添加is_del字段标记删除【技巧】  PHP 中 require() 语句返回值的用法详解  微信里的php文件怎么变mp4_微信接收php转mp4操作步骤【操作】  Win11怎么关闭右下角弹窗_Win11拦截系统通知广告【设置】  如何在Golang中处理数据库事务错误_回滚和日志记录  Win11怎么设置指纹解锁 Win11笔记本录入指纹登录【教程】  Windows怎样关闭锁屏广告_Windows关闭锁屏广告方法【教程】  C++中的Pimpl idiom是什么,有什么好处?(隐藏实现)  php中$this和::能混用吗_对象与静态作用域冲突解决【方法】  Win10怎么卸载剪映_Win10彻底卸载剪映方法【步骤】  Win11如何隐藏桌面图标 Win11一键隐藏/显示桌面图标【指南】  ACF 教程:正确更新嵌套在多层 Group 字段内的子字段  Go语言中slice追加操作的底层共享机制解析  Win10怎样清理C盘Steam游戏缓存_Win10清理Steam游戏缓存步骤【步骤】  Windows蓝屏BAD_POOL_HEADER故障详解_蓝屏池损坏错误修复指南  如何在Golang中解压文件_Golang compress/gzip解压操作方法  c++如何利用doxygen生成开发文档_c++ 代码注释规范与HTML文档导出【案例】  Python如何创建带属性的XML节点  TestNG的testng.xml配置文件怎么写  如何使用Golang实现路由分组管理_Golang路由分组与权限控制方法  如何用列表一次性对 DataFrame 的指定列应用字典映射  为什么Go需要go mod文件_Go go mod文件作用说明  LINUX怎么查看进程_LINUX ps命令查看运行服务  如何在Golang中处理JSON字段缺失_Golangjson解析字段校验方法  Linux如何安装Golang环境_Linux下Go语言开发包配置【方法】  Win11怎么设置默认终端应用_Windows11开发者选项终端  如何使用Golang实现RPC序列化与反序列化_Golang RPC数据编码与解码方法  Windows电脑如何进入安全模式?(多种按键方法)  Win11怎么更改计算机名_Windows11系统信息重命名设备教程  Windows10如何更改任务栏高度_Win10解除锁定调整大小  ACF 教程:如何正确更新嵌套在多层 Group 字段内的子字段  如何在Golang中实现微服务负载均衡_Golang负载均衡策略与实现示例  如何使用Golang encoding/json解析JSON_Golang encoding/json解析与序列化示例  mac怎么退出id_MAC退出iCloud账号与Apple ID切换【指南】  php下载安装后memory_limit怎么设置_内存限制调整【技巧】  为什么本地php环境运行php脚本卡顿_php执行效率优化方法与设置【说明】  Win11无法安装软件怎么办_Win11解除应用安装限制设置【修复】  如何使用Golang recover捕获panic_防止程序崩溃并处理异常  php8.4匿名类怎么用_php8.4匿名类创建与使用场景【介绍】  Windows驱动无法加载错误解决方法_驱动签名验证失败处理步骤  Python脚本参数接收_sys与argparse解析【指导】  C#怎么使用委托和事件 C# delegate与event编程方法 

 2025-12-30

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

致胜网络推广营销网


致胜网络推广营销网

致胜网络推广营销网专注海外推广十年,是谷歌推广.Facebook广告全球合作伙伴,我们精英化的技术团队为企业提供谷歌海外推广+外贸网站建设+网站维护运营+Google SEO优化+社交营销为您提供一站式海外营销服务。

 915688610

 17370845950

 915688610@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.