定义
中介者模式(Mediator Pattern)是一种行为设计模式。它通过引入一个中介者对象来封装一系列对象之间的交互,使得这些对象之间不再直接相互引用,而是通过中介者来进行通信。这样可以降低对象之间的耦合度,使得系统的结构更加清晰,易于维护和扩展。
UML 类图及主要角色
- 抽象中介者(Mediator):
定义了一个接口,用于与各同事(Colleague)对象进行通信。在 C++ 中,通常是一个抽象类,包含抽象的通知方法,用于接收同事对象发送的消息并进行处理。 - 具体中介者(Concrete Mediator):
实现了抽象中介者中的接口,它了解并维护各个同事对象的引用,负责协调各个同事对象之间的交互。当收到一个同事对象的消息时,它会根据业务逻辑决定将消息转发给哪些其他同事对象。 - 抽象同事(Colleague):
定义了同事类的接口,每个同事对象都知道它的中介者对象,并且在需要与其他同事对象通信时,通过中介者对象来发送消息。 - 具体同事(Concrete Colleague):
实现了抽象同事类的接口,具体同事对象包含自身的业务逻辑,并通过中介者对象来和其他同事对象进行通信。例如,在一个聊天系统中,每个用户(具体同事)可以通过聊天服务器(具体中介者)来发送和接收消息,而不是直接与其他用户通信。
简单示例:简单的聊天系统
抽象中介者类
class ChatMediator {
public:
virtual void sendMessage(const std::string& msg, class ChatUser* user) = 0;
};
具体中介者类
class ChatRoom : public ChatMediator {
private:
std::vector<ChatUser*> users;
public:
void addUser(ChatUser* user) {
users.push_back(user);
}
void sendMessage(const std::string& msg, ChatUser* user) override {
for (ChatUser* u : users) {
if (u!= user) {
u->receive(msg);
}
}
}
};
抽象同事类
class ChatUser {
protected:
ChatMediator* mediator;
public:
ChatUser(ChatMediator* med) : mediator(med) {}
virtual void send(const std::string& msg) = 0;
virtual void receive(const std::string& msg) = 0;
};
具体同事类
class ChatUserImpl : public ChatUser {
private:
std::string name;
public:
ChatUserImpl(ChatMediator* med, const std::string& n) : ChatUser(med), name(n) {}
void send(const std::string& msg) override {
mediator->sendMessage(msg, this);
}
void receive(const std::string& msg) override {
std::cout << name << " received message: " << msg << std::endl;
}
};
使用示例
int main() {
ChatRoom room;
ChatUser* user1 = new ChatUserImpl(&room, "User1");
ChatUser* user2 = new ChatUserImpl(&room, "User2");
room.addUser(user1);
room.addUser(user2);
user1->send("Hello!");
delete user1;
delete user2;
return 0;
}
在这个示例中,ChatMediator是抽象中介者,ChatRoom是具体中介者,负责管理用户并转发消息。ChatUser是抽象同事,ChatUserImpl是具体同事,用户通过中介者(聊天房间)来发送和接收消息。
优点
- 降低耦合度:
减少了同事对象之间的直接依赖,使得各个同事对象可以独立地变化和扩展,而不会影响到其他同事对象。例如在复杂的软件系统中,不同模块之间的通信通过中介者进行,模块内部的修改不会直接影响其他模块。 - 集中控制交互逻辑:
中介者对象可以集中管理和协调同事对象之间的交互,使得交互逻辑更加清晰。比如在游戏开发中,游戏场景中的各个游戏对象之间的交互(如碰撞检测、触发事件等)可以通过一个场景中介者来统一管理。
缺点
- 中介者可能会变得复杂:
如果同事对象之间的交互过于复杂,中介者对象可能会包含大量的逻辑来协调这些交互,导致中介者类变得庞大和复杂,难以维护。 - 系统的可扩展性可能会受到限制:
当需要添加新的同事对象或者新的交互方式时,可能需要修改中介者类的代码,这可能会对系统的扩展性产生一定的影响。不过,通过合理的设计和接口规划,可以在一定程度上减轻这种影响。