首页 > 编程笔记 > C++笔记 阅读:16

中介者模式详解(附带C++实例)

在系统设计中,随着组件数量的增加和交互的复杂化,有效地管理这些组件之间的通信成为一个不容忽视的挑战。中介者模式为我们提供了一种优雅的解决方案,它通过一个中介对象来封装一系列对象之间的交互方式。

中介者模式特别适用于以下几种应用需求:
在思考这些需求的时候,我们可以问自己几个问题来评估是否适合采用中介者模式:
当我们对这些问题有了答案后,就可以更深入地探讨中介者模式的具体应用了。

中介者模式中的角色

中介者模式如下图所示:


图 1 中介者模式

它主要包含以下几个关键角色:
例如,在一个在线协作系统中,可能包括文档编辑器、聊天窗口、用户列表等多个组件。这些组件需要频繁地互相交流,比如更新文档状态、发送消息通知等。在没有中介者的设计中,这些组件之间的直接引用和调用会导致系统耦合度增加,使得维护和扩展变得困难。

引入中介者后,所有组件的交互都通过中介者对象进行。当用户在文档编辑器中做出更改时,编辑器只需通知中介者,由中介者来通知其他相关组件更新状态。这种方式解除了组件之间的直接依赖关系,使得每个组件只需要与中介者交互。

这样设计,不仅简化了组件之间的通信逻辑,还降低了系统的耦合度,组件的替换和修改也变得更加方便。即使交互逻辑发生变化,也只需调整中介者,而无须修改所有组件的代码,从而提高了系统的可维护性和可扩展性。

中介者模式示例展示

#include <iostream>
#include <vector>

// 中介者接口定义与各组件通信的方法
class Mediator {
public:
    virtual void communicate(const std::string& message, class Colleague* colleague) = 0;
};

// 同事类接口,组件知晓中介者但不知晓其他同事类
class Colleague {
protected:
    Mediator* mediator;
public:
    Colleague(Mediator* m) : mediator(m) {}
    virtual void receiveMessage(const std::string& message) = 0;
    virtual void sendMessage(const std::string& message) = 0;
};

// 具体中介者,实现中介者接口,协调各组件间的交互
class ConcreteMediator : public Mediator {
private:
    std::vector<Colleague*> colleagues;
public:
    void addColleague(Colleague* colleague) {
        colleagues.push_back(colleague);
    }

    void communicate(const std::string& message, Colleague* originator) override {
        for (auto* colleague : colleagues) {
            if (colleague != originator) { // 发送信息给除了发起者之外的所有同事
                colleague->receiveMessage(message);
            }
        }
    }
};

// 具体同事类A
class ConcreteColleagueA : public Colleague {
public:
    ConcreteColleagueA(Mediator* m) : Colleague(m) {}

    void receiveMessage(const std::string& message) override {
        std::cout << "同事A收到消息:" << message << std::endl;
    }

    void sendMessage(const std::string& message) override {
        std::cout << "同事A发送消息:" << message << std::endl;
        mediator->communicate(message, this);
    }
};

// 具体同事类B
class ConcreteColleagueB : public Colleague {
public:
    ConcreteColleagueB(Mediator* m) : Colleague(m) {}

    void receiveMessage(const std::string& message) override {
        std::cout << "同事B收到消息:" << message << std::endl;
    }

    void sendMessage(const std::string& message) override {
        std::cout << "同事B发送消息:" << message << std::endl;
        mediator->communicate(message, this);
    }
};

int main() {
    ConcreteMediator mediator;
    ConcreteColleagueA colleagueA(&mediator);
    ConcreteColleagueB colleagueB(&mediator);

    mediator.addColleague(&colleagueA);
    mediator.addColleague(&colleagueB);

    colleagueA.sendMessage("你好,同事B");
    colleagueB.sendMessage("你好,同事A,今天感觉怎么样?");

    return 0;
}
运行结果为:

同事A发送消息:你好,同事B
同事B收到消息:你好,同事B
同事B发送消息:你好,同事A,今天感觉怎么样?
同事A收到消息:你好,同事A,今天感觉怎么样?

在这个示例中:
当一个具体同事类(比如 ConcreteColleagueA)发送消息时,它会调用中介者的 communicate 方法,这个方法会让其他的同事类接收到消息,从而完成各个组件之间的交互。

中介者模式的作用

中介者模式在软件设计中的主要作用如下:
这样可以避免以下问题:
总之,中介者模式通过将交互逻辑集中到一个中介者中来管理,降低了系统内各部分之间的耦合,简化了组件的设计和维护,提高了系统的灵活性和可扩展性。这种模式特别适合用于复杂的交互系统,例如大型 GUI 应用程序或业务流程管理系统。

相关文章