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

待扩展

  • 添加消息历史记录功能
  • 实现消息撤回机制
  • 增加用户权限验证
  • 支持@指定用户的群组消息
相关推荐
微露清风6 小时前
系统性学习C++-第十八讲-封装红黑树实现myset与mymap
java·c++·学习
CSARImage6 小时前
C++读取exe程序标准输出
c++
一只小bit6 小时前
Qt 常用控件详解:按钮类 / 显示类 / 输入类属性、信号与实战示例
前端·c++·qt·gui
一条大祥脚6 小时前
26.1.9 轮廓线dp 状压最短路 构造
数据结构·c++·算法
项目題供诗7 小时前
C语言基础(一)
c++
@areok@8 小时前
C++opencv图片(mat)传入C#bitmap图片
开发语言·c++·opencv
鸽芷咕8 小时前
【2025年度总结】时光知味,三载同行:落笔皆是沉淀,前行自有光芒
linux·c++·人工智能·2025年度总结
羑悻的小杀马特8 小时前
指尖敲代码,笔尖写成长:2025年度总结与那些没说出口的碎碎念
linux·c++·博客之星·2025年度总结
linweidong8 小时前
C++thread pool(线程池)设计应关注哪些扩展性问题?
java·数据库·c++
cpp_25018 小时前
P2708 硬币翻转
数据结构·c++·算法·题解·洛谷