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

待扩展

  • 添加消息历史记录功能
  • 实现消息撤回机制
  • 增加用户权限验证
  • 支持@指定用户的群组消息
相关推荐
REDcker7 小时前
gRPC开发者快速入门
服务器·c++·后端·grpc
doupoa7 小时前
内存指针是什么?为什么指针还要有偏移量?
android·c++
冉佳驹7 小时前
C++ ——— 异常处理的核心机制和智能指针管理
c++·异常捕获·异常继承体与多态·重载抛异常·raii思想·智能指针shared_ptr·weak_ptr指针
C++ 老炮儿的技术栈7 小时前
Qt 编写 TcpClient 程序 详细步骤
c语言·开发语言·数据库·c++·qt·算法
yuuki2332337 小时前
【C++】继承
开发语言·c++·windows
梵刹古音7 小时前
【C++】 析构函数
开发语言·c++
wangjialelele8 小时前
Linux下的IO操作以及ext系列文件系统
linux·运维·服务器·c语言·c++·个人开发
打工哪有不疯的8 小时前
使用 MSYS2 为 Qt (MinGW 32/64位) 完美配置 OpenSSL
c++·qt
代码游侠8 小时前
C语言核心概念复习——C语言基础阶段
linux·开发语言·c++·学习
㓗冽8 小时前
60题之内难题分析
开发语言·c++·算法