中介者模式 (Mediator Pattern)

中介者模式 (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 → 具体同事类
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值