C++ 设计模式-中介者模式

聊天室

cpp 复制代码
#include <iostream>
#include <string>
#include <unordered_map>
#include <vector>

// 前向声明
class User;

// 抽象中介者
class ChatMediator {
public:
    virtual ~ChatMediator() = default;
    virtual void broadcast(const std::string& msg, User* sender) = 0;
    virtual void privateMessage(const std::string& msg, 
                              User* sender, 
                              const std::string& receiver) = 0;
};

// 抽象用户类
class User {
protected:
    ChatMediator* mediator_;
    std::string name_;

public:
    User(ChatMediator* mediator, std::string name)
        : mediator_(mediator), name_(std::move(name)) {}
    
    virtual ~User() = default;

    // 发送广播
    void sendToAll(const std::string& msg) {
        mediator_->broadcast(msg, this);
    }

    // 发送私信
    void sendPrivate(const std::string& msg, 
                   const std::string& receiver) {
        mediator_->privateMessage(msg, this, receiver);
    }

    virtual void receive(const std::string& msg, 
                       const User* sender = nullptr) const {
        std::cout << "[" << name_ << "] 收到";
        if(sender) std::cout << "来自[" << sender->name_ << "]的";
        std::cout << "消息: " << msg << std::endl;
    }

    std::string getName() const { return name_; }
};

// 具体中介者
class ChatRoom : public ChatMediator {
private:
    std::unordered_map<std::string, User*> users_;

public:
    void addUser(User* user) {
        users_.emplace(user->getName(), user);
    }

    void broadcast(const std::string& msg, User* sender) override {
        for (auto& [name, user] : users_) {
            if (user != sender) user->receive(msg, sender);
        }
    }

    void privateMessage(const std::string& msg, 
                      User* sender,
                      const std::string& receiver) override {
        if (auto it = users_.find(receiver); it != users_.end()) {
            it->second->receive(msg, sender);
        } else {
            sender->receive("用户不存在: " + receiver);
        }
    }
};

// 客户端使用
int main() {
    ChatRoom chatRoom;

    User alice(&chatRoom, "Alice");
    User bob(&chatRoom, "Bob");
    User charlie(&chatRoom, "Charlie");

    chatRoom.addUser(&alice);
    chatRoom.addUser(&bob);
    chatRoom.addUser(&charlie);

    // 广播消息
    alice.sendToAll("大家好!");

    // 私信消息
    bob.sendPrivate("今晚一起吃饭吗?", "Alice");
    charlie.sendPrivate("测试消息", "UnknownUser");

    return 0;
}

关键说明:

  1. 明确消息类型

    • broadcast():广播给所有用户(排除发送者)
    • privateMessage():精确发送给指定用户
  2. 输出结果

    [Bob] 收到来自[Alice]的消息: 大家好!
    [Charlie] 收到来自[Alice]的消息: 大家好!
    [Alice] 收到来自[Bob]的消息: 今晚一起吃饭吗?
    [Charlie] 收到消息: 用户不存在: UnknownUser

  3. 模式优势体现

    • 完全解耦:用户之间无需知道彼此存在
    • 集中路由:所有消息逻辑在中介者中处理
    • 灵活扩展:可轻松添加群组消息、消息过滤等新功能
  4. 设计亮点

    • 使用哈希表快速查找用户(O(1)时间复杂度)
    • 接收消息时显示发送者信息
    • 处理用户不存在等异常情况

模式结构示意图:

复制代码
           +----------------+
           |  ChatMediator  |
           +----------------+
           | broadcast()    |
           | privateMessage()|
           +--------+-------+
                    ʌ
                    | 中介
+-------------+     |     +-------------+
|    User     +-----+-----+  ChatRoom   |
+-------------+           +-------------+
| sendToAll() |           | 用户管理    |
| sendPrivate()           | 消息路由    |
+-------------+           +-------------+

何时使用中介者模式:

  1. 当对象间存在 复杂网状通信关系
  2. 需要 集中控制 多个对象间的交互时
  3. 系统需要 动态调整通信规则

待扩展

  • 添加消息历史记录功能
  • 实现消息撤回机制
  • 增加用户权限验证
  • 支持@指定用户的群组消息
相关推荐
uyeonashi5 分钟前
【Boost搜索引擎】构建Boost站内搜索引擎实践
开发语言·c++·搜索引擎
Smile丶凉轩3 小时前
Qt 界面优化(绘图)
开发语言·数据库·c++·qt
small_wh1te_coder5 小时前
从经典力扣题发掘DFS与记忆化搜索的本质 -从矩阵最长递增路径入手 一步步探究dfs思维优化与编程深度思考
c语言·数据结构·c++·stm32·算法·leetcode·深度优先
hjjdebug7 小时前
constexpr 关键字的意义(入门)
c++·constexpr
虾球xz8 小时前
游戏引擎学习第282天:Z轴移动与摄像机运动
c++·学习·游戏引擎
.小墨迹8 小时前
Apollo学习——planning模块(3)之planning_base
linux·开发语言·c++·学习·自动驾驶
龙湾开发8 小时前
计算机图形学编程(使用OpenGL和C++)(第2版)学习笔记 10.增强表面细节(一)过程式凹凸贴图
c++·笔记·学习·3d·图形渲染
德亦周8 小时前
如何在Mac电脑上的VScode去配置C/C++环境
c++·vscode·macos
XiaoyaoCarter9 小时前
每日一道leetcode(新学数据结构版)
数据结构·c++·算法·leetcode·职场和发展·哈希算法·前缀树
八月的雨季 最後的冰吻9 小时前
SIP协议栈--osip源码梳理
linux·服务器·网络·c++·网络协议