中介者类不能直接持有具体同事类指针,否则会引发编译依赖和双向耦合;应只持抽象基类colleague指针或weak_ptr,通过前向声明、角色标识符和虚函数实现解耦与轻量协作。

中介者类为什么不能直接持有具体同事类的指针?
因为那样会重新引入编译依赖和双向耦合——同事类修改时,中介者也要重编译;反之亦然。轻量级的关键在于“只认接口,不认实现”。
- 用抽象基类
Colleague定义统一通信入口(如notify()、send()),所有具体同事继承它 - 中介者(
Mediator)只保存std::vector<colleague></colleague>或std::weak_ptr<colleague></colleague>,避免循环引用 - 若用裸指针,需确保同事生命周期长于中介者;若用
std::weak_ptr,必须搭配std::shared_ptr管理同事对象
如何让同事类在不依赖中介者头文件的前提下发送消息?
靠前向声明 + 指针/引用参数解耦。同事类头文件里不需要 #include "Mediator.h",只需要知道中介者存在即可。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 在同事类头文件顶部加前向声明:
class Mediator; - 将
Mediator*作为构造函数参数或setMediator()方法参数传入,但不存储其完整类型 - 实际调用中介者方法时,把逻辑移到 .cpp 文件中,在那里
#include "Mediator.h"—— 编译依赖被隔离 - 错误示范:
Mediator m;或std::unique_ptr<mediator></mediator>直接定义在头文件里,会强制包含其定义
Mediator::notify() 怎么避免硬编码同事类型判断?
硬写 if (dynamic_cast<button>(sender)) { ... }</button> 会破坏开闭原则,也难维护。轻量级做法是用“角色标识符”代替类型检查。
- 给每个同事分配唯一
std::string role或枚举值(如enum class Role { BUTTON, TEXTBOX, LISTBOX };) - 中介者用
std::map<role std::function>></role>或简单 switch 分发逻辑 - 同事调用
mediator->notify(role, data),而不是mediator->onButtonClicked()—— 后者会让中介者接口膨胀 - 注意:不要用 RTTI 做运行时多态分发,那是重量级方案;角色 ID 是编译期可控、零成本抽象
为什么不用模板实现通用中介者?
模板看似能泛化,但会导致实例爆炸、链接失败、调试困难——尤其当同事类型多且分散在不同编译单元时。
-
template<typename t> class MediatorT { ... };</typename>每个T都生成一份代码,无法统一管理多种同事 - 无法在运行时动态增删同事(比如插件系统),模板类型必须编译期确定
- 真正轻量的中介者应该只有一个实现,靠虚函数或回调注册支撑多类型协作
- 例外:仅用于两个固定类型的极简场景(如
DialogBox和OkButton),可用模板局部优化,但不属于通用轻量模式
"UI")失去控制力,太细(如 "LoginButton_ClickHandler")又变相绑定业务逻辑。建议从最小可测试交互单元起步,比如一个表单里“输入框内容变更 → 实时校验 → 按钮状态更新”,这三者构成一组角色闭环,其余都往后推。C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










