1. 模式定义
中介者模式是一种行为设计模式,它通过引入一个中介对象来封装一系列对象之间的交互,从而降低这些对象之间的耦合度。中介者使对象之间不需要显式地相互引用,从而使其可以独立地改变它们之间的交互。
2. 核心思想
用一个中介对象来封装多个对象间的交互关系,使得各对象不需要显式地相互引用,从而降低耦合度,并可以独立地改变它们之间的交互。
解耦多个同事对象之间的交互关系。每个对象都持有中介者对象的引用,只跟中介者对象打交道。我们通过中介者对象统一管理这些交互关系。
3. 主要角色
-
Mediator(抽象中介者):定义同事对象到中介者对象的接口
-
ConcreteMediator(具体中介者):实现抽象中介者的接口,协调各个同事对象的交互
-
Colleague(同事类):每个同事对象都知道它的中介者对象,同事对象之间不直接通信,而是通过中介者进行通信
-
ConcreteColleague(具体同事类):实现同事类的接口

4. 应用场景
-
系统中对象之间存在复杂的引用关系,导致依赖关系结构混乱且难以复用
-
多个对象之间的交互操作紧密耦合,导致难以独立修改这些行为
-
需要定义一个分布在多个类中的行为,但又不想生成太多子类
5. 模式优缺点
优点:
-
降低耦合度:将多个对象间的交互封装在中介者中,对象间不直接引用
-
集中控制:将交互逻辑集中在中介者中,便于维护和修改
-
简化对象协议:用一对多的交互代替多对多的交互
-
提高可复用性:同事类之间不直接通信,可以独立变化和复用
缺点:
-
中介者复杂化:中介者可能变得过于复杂,承担过多责任
-
性能影响:对象间通信必须通过中介者,可能影响性能
-
单点故障:中介者成为系统瓶颈,中介者故障会影响整个系统
代码
cpp
#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include <algorithm>
#include <ctime>
// 前向声明
class User;
// 抽象中介者:聊天室
class ChatRoomMediator {
public:
virtual ~ChatRoomMediator() = default;
virtual void sendMessage(const std::string& message, User* user) = 0;
virtual void addUser(User* user) = 0;
};
// 抽象同事类:用户
class User {
protected:
ChatRoomMediator* mediator;
std::string name;
public:
User(const std::string& name, ChatRoomMediator* mediator)
: name(name), mediator(mediator) {
if (mediator) {
mediator->addUser(this);
}
}
virtual ~User() = default;
virtual void send(const std::string& message) = 0;
virtual void receive(const std::string& message) = 0;
std::string getName() const {
return name;
}
void setMediator(ChatRoomMediator* newMediator) {
mediator = newMediator;
}
};
cpp
// 具体中介者:聊天室
class ChatRoom : public ChatRoomMediator {
private:
std::string name;
std::vector<User*> users;
std::string getCurrentTime() {
time_t now = time(0);
char* dt = ctime(&now);
std::string timeStr(dt);
// 移除换行符
if (!timeStr.empty() && timeStr[timeStr.length()-1] == '\n') {
timeStr.erase(timeStr.length()-1);
}
return timeStr;
}
public:
explicit ChatRoom(const std::string& name) : name(name) {
std::cout << "聊天室 '" << name << "' 已创建\n";
}
void addUser(User* user) override {
users.push_back(user);
std::cout << "用户 '" << user->getName() << "' 加入了聊天室 '" << name << "'\n";
}
void sendMessage(const std::string& message, User* sender) override {
std::string formattedMessage = "[" + getCurrentTime() + "] " +
sender->getName() + ": " + message;
std::cout << "聊天室 '" << name << "' 转发消息: " << formattedMessage << "\n";
// 广播消息给所有用户(除了发送者)
for (User* user : users) {
if (user != sender) {
user->receive(formattedMessage);
}
}
}
// 私聊功能
void sendPrivateMessage(const std::string& message, User* sender, User* receiver) {
std::string formattedMessage = "[" + getCurrentTime() + "] [私聊] " +
sender->getName() + " 对你说: " + message;
std::cout << "聊天室 '" << name << "' 转发私聊消息\n";
receiver->receive(formattedMessage);
}
// 获取在线用户列表
void listUsers() const {
std::cout << "聊天室 '" << name << "' 在线用户 (" << users.size() << "人):\n";
for (const User* user : users) {
std::cout << " - " << user->getName() << "\n";
}
}
std::string getName() const {
return name;
}
};
cpp
// 具体同事类:普通用户
class RegularUser : public User {
public:
RegularUser(const std::string& name, ChatRoomMediator* mediator)
: User(name, mediator) {}
void send(const std::string& message) override {
std::cout << name << " 发送消息: " << message << "\n";
if (mediator) {
mediator->sendMessage(message, this);
}
}
void receive(const std::string& message) override {
std::cout << name << " 收到消息: " << message << "\n";
}
};
// 具体同事类:管理员用户
class AdminUser : public User {
public:
AdminUser(const std::string& name, ChatRoomMediator* mediator)
: User(name, mediator) {}
void send(const std::string& message) override {
std::cout << "[管理员] " << name << " 发送消息: " << message << "\n";
if (mediator) {
mediator->sendMessage(message, this);
}
}
void receive(const std::string& message) override {
std::cout << "[管理员] " << name << " 收到消息: " << message << "\n";
}
void sendAnnouncement(const std::string& announcement) {
std::string formattedMsg = "【系统公告】" + announcement;
send(formattedMsg);
}
};
// 具体同事类:机器人用户
class BotUser : public User {
private:
std::vector<std::pair<std::string, std::string>> responses = {
{"你好", "你好!我是聊天机器人。"},
{"天气", "今天天气晴朗,气温25度。"},
{"时间", "当前时间是: "},
{"帮助", "我可以回答: 你好, 天气, 时间, 帮助"}
};
public:
BotUser(const std::string& name, ChatRoomMediator* mediator)
: User(name, mediator) {}
void send(const std::string& message) override {
// 机器人通常不主动发送消息
std::cout << "[机器人] " << name << " 处理消息: " << message << "\n";
}
void receive(const std::string& message) override {
std::cout << "[机器人] " << name << " 收到消息: " << message << "\n";
// 检查是否需要响应
for (const auto& pair : responses) {
if (message.find(pair.first) != std::string::npos) {
std::string response = pair.second;
if (pair.first == "时间") {
response += ChatRoom("").getCurrentTime(); // 获取时间
}
send(response);
break;
}
}
}
};
cpp
int main() {
std::cout << "===== 聊天室系统演示 =====\n\n";
// 创建聊天室(中介者)
ChatRoom mainChatRoom("主聊天室");
ChatRoom gameChatRoom("游戏聊天室");
// 创建用户(同事类)
RegularUser alice("Alice", &mainChatRoom);
RegularUser bob("Bob", &mainChatRoom);
AdminUser admin("系统管理员", &mainChatRoom);
BotUser chatbot("小助手", &mainChatRoom);
std::cout << "\n";
// 显示在线用户
mainChatRoom.listUsers();
std::cout << "\n";
// 用户间发送消息(通过中介者)
std::cout << "=== 开始聊天 ===\n";
alice.send("大家好,我是Alice!");
std::cout << "\n";
bob.send("你好Alice,我是Bob!");
std::cout << "\n";
admin.sendAnnouncement("欢迎新用户加入聊天室!");
std::cout << "\n";
// 测试机器人响应
alice.send("小助手,你好");
std::cout << "\n";
bob.send("小助手,今天天气怎么样?");
std::cout << "\n";
alice.send("小助手,现在几点了?");
std::cout << "\n";
// 用户切换到另一个聊天室
std::cout << "\n=== 切换聊天室 ===\n";
alice.setMediator(&gameChatRoom);
gameChatRoom.addUser(&alice);
std::cout << "\n";
bob.setMediator(&gameChatRoom);
gameChatRoom.addUser(&bob);
std::cout << "\n";
// 在新聊天室中聊天
gameChatRoom.listUsers();
std::cout << "\n";
alice.send("有人要一起玩游戏吗?");
std::cout << "\n";
bob.send("好啊,Alice!玩什么游戏?");
std::cout << "\n";
// 私聊功能演示
std::cout << "\n=== 私聊功能 ===\n";
gameChatRoom.sendPrivateMessage("我们玩英雄联盟吧?", &alice, &bob);
std::cout << "\n";
return 0;
}