中介者模式 (Mediator Pattern)
意图:用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
基础组件
- Mediator (中介者):定义对象间通信的接口
- ConcreteMediator (具体中介者):协调各对象,实现协作行为
- Colleague (同事类):知道其中介者,通过中介者与其他同事通信
- ConcreteColleague (具体同事类):实现自身行为,并在需要时通过中介者与其他同事通信
继承/实现关系
Mediator <|-- ConcreteMediator
Colleague <|-- ConcreteColleague
ConcreteMediator --> ConcreteColleague (管理同事对象)
ConcreteColleague --> Mediator (与中介者通信)
应用场景
- 对象间存在复杂的网状引用关系
- 需要封装多个对象间的交互
- 需要集中控制对象间的交互逻辑
C++ 实现(聊天室场景)
#include <iostream>
#include <string>
#include <memory>
#include <vector>
/*
* 中介者模式
* 意图:用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
* 基础组件:
* - Mediator (中介者):定义对象间通信的接口
* - ConcreteMediator (具体中介者):协调各对象,实现协作行为
* - Colleague (同事类):知道其中介者,通过中介者与其他同事通信
* - ConcreteColleague (具体同事类):实现自身行为,并在需要时通过中介者与其他同事通信
* 继承/实现关系:
* ConcreteMediator 继承自 Mediator。
* ConcreteColleague 继承自 Colleague。
* ConcreteMediator 持有多个 ConcreteColleague 的引用,并负责它们之间的通信。
* ConcreteColleague 通过 Mediator 接口与其他同事通信。
*/
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 {
public:
User(const std::string& name, ChatRoomMediator* mediator)
: name_(name), mediator_(mediator) {
mediator_->addUser(this);
}
void send(const std::string& message) {
mediator_->sendMessage(message, this);
}
virtual void receive(const std::string& message, User* sender) {
std::cout << name_ << " received from " << sender->name_ << ": " << message << "\n";
}
const std::string& getName() const { return name_; }
protected:
std::string name_;
// 内部持有一个中介者的引用,从而通过它与其他用户通信(发送和接受消息)
ChatRoomMediator* mediator_;
};
// 具体同事类:普通用户
class NormalUser : public User {
public:
using User::User;
};
// 具体同事类:管理员
class AdminUser : public User {
public:
using User::User;
void receive(const std::string& message, User* sender) override {
std::cout << "[Admin] " << name_ << " received from "
<< sender->getName() << ": " << message << "\n";
}
};
// 具体中介者:聊天室实现
class ChatRoom : public ChatRoomMediator {
public:
void addUser(User* user) override {
users_.push_back(user);
}
void sendMessage(const std::string& message, User* user) override {
// 对聊天室中的所有用户进行广播,除了发送者本身
for (auto u : users_) {
if (u != user) {
u->receive(message, user);
}
}
}
private:
std::vector<User*> users_;
};
void MediatorPattern()
{
std::cout << std::string(13, '-') << " Mediator Pattern " << std::string(13, '-') << std::endl;
auto chatRoom = std::make_shared<ChatRoom>();
// 重点是同事类也需要内部存储一个中介者的引用,来实现和其他同事类的通信
NormalUser alice("Alice", chatRoom.get());
NormalUser bob("Bob", chatRoom.get());
AdminUser admin("SystemAdmin", chatRoom.get());
// 这段代码还可以扩展,使得用户可以给指定的用户发送消息,而非广播给所有用户
alice.send("Hello, everyone!");
bob.send("Hi Alice!");
admin.send("Welcome to the chat room!");
}
组件对应关系
ChatRoomMediator→ 中介者接口ChatRoom→ 具体中介者User→ 同事类NormalUser/AdminUser→ 具体同事类
236

被折叠的 条评论
为什么被折叠?



