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

发布于:2025-02-22 ⋅ 阅读:(153) ⋅ 点赞:(0)

聊天室

#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
  1. 模式优势体现

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

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

模式结构示意图:

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

何时使用中介者模式:

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

待扩展

  • 添加消息历史记录功能
  • 实现消息撤回机制
  • 增加用户权限验证
  • 支持@指定用户的群组消息

网站公告

今日签到

点亮在社区的每一天
去签到