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. 系统需要 动态调整通信规则

待扩展

  • 添加消息历史记录功能
  • 实现消息撤回机制
  • 增加用户权限验证
  • 支持@指定用户的群组消息
相关推荐
浆果02072 小时前
NanoTrack C++ — RK3588 实时目标跟踪
c++·目标跟踪·rk3588
ysa0510302 小时前
【并查集】判环
c++·笔记·算法
持力行3 小时前
C/C++ 中的 char*:它标识数组吗?为什么能用下标访问?
c语言·c++
汉克老师4 小时前
GESP2026年6月认证C++六级( 第三部分编程题(2、满二叉树))精讲
c++·深度优先·树形dp·满二叉树·gesp六级·树形dfs
踮起脚看烟花5 小时前
多人聊天室实现v2.0
c++·信息与通信
梦帮科技5 小时前
UE5 GAS 实战:用 Gameplay Ability System 搭建「赛博修真」境界与技能体系
c++·人工智能·python·ue5·c#
旖-旎5 小时前
QT系统篇(5)(下)
开发语言·c++·qt
99乘法口诀万物皆可变5 小时前
PcanToVectorXL_V01:打通 Vector 与 PCAN 的双向 CAN/CAN‑FD 桥梁
c++·学习
liulun5 小时前
C++ WinRT中的事件
开发语言·c++
whitelbwwww6 小时前
c++运行onnx模型
开发语言·c++