中介者模式 – 统一协调,对象解耦
中介者模式是一种行为设计模式,它允许你减少多个对象或类之间的直接通信,从而减少它们之间的依赖关系,提高模块化,并促进代码的可维护性。中介者通过成为对象之间通信的中心点,使得对象不需要显式地相互引用,从而使其更容易独立地改变它们之间的交云。
组成
- 中介者(Mediator)接口:定义了与各个同事(Colleague)对象通信的接口。
- 具体中介者(Concrete Mediator):实现中介者接口,并协调各个同事对象之间的交云。具体中介者知道所有的同事类并负责它们之间的交云。
- 同事类(Colleague):定义了各个同事对象执行的操作。它不知道其他同事类,但知道中介者对象。
- 具体同事类(Concrete Colleague):实现同事类,它的行为由中介者对象协调。
优点
- 降低类间的耦合度:通过使对象不直接交云而是通过中介者交云,可以减少类间的依赖关系,提高类的复用性。
- 集中控制交云:中介者模式将对象间的交云集中到一个中介者对象中,使得对象间的交云更加容易管理和维护。
- 提高可扩展性:增加新的同事类或者改变同事之间的交云,只需要修改中介者,不需要修改同事类,这样就提高了系统的可扩展性。
- 简化对象协议:通过使对象不直接交云,对象之间不需要持有对方的引用,从而简化了系统中的对象协议。
使用场景
- 系统中对象之间的交云非常复杂:当一个系统中对象之间的交云非常复杂,直接的通信会导致交云的多对多关系难以管理时,使用中介者模式可以将复杂的网状结构转换为更简单的形式。
- 系统想要在对象之间实现松耦合:当系统需要提高对象之间的独立性,使得它们不直接交云,从而可以独立地改变它们之间的交云时,中介者模式提供了一种方便的方式。
- 对象间的交云行为是集中在一处变化的:当多个类相互作用,但是这种交云行为在未来可能会发生变化,或者现在就很难设计时,将这种交云行为集中到一个中介者中可以更容易地更改交云行为。
- 模块间需要通过某种方式通信,但是又希望模块间保持松耦合:在开发模块化的系统时,中介者模式可以用来在各个模块之间建立一个中介对象,这样各个模块就不需要直接交云,而是通过中介对象来进行通信,从而保持了模块间的松耦合。
实现
- 中介者(Mediator)接口:定义了与各个同事(Colleague)对象通信的接口。
class Mediator {
public:
virtual void send(const std::string& message, Colleague* colleague) = 0;
};
- 具体中介者(Concrete Mediator):实现中介者接口,并协调各个同事对象之间的交云。具体中介者知道所有的同事类并负责它们之间的交云。
// 具体中介者
class ConcreteMediator : public Mediator {
private:
ConcreteColleagueA* colleagueA;
ConcreteColleagueB* colleagueB;
public:
void setColleagueA(ConcreteColleagueA* a) {
colleagueA = a;
}
void setColleagueB(ConcreteColleagueB* b) {
colleagueB = b;
}
void send(const std::string& message, Colleague* colleague) override {
if (colleague == colleagueA) {
colleagueB->receive(message);
} else {
colleagueA->receive(message);
}
}
};
- 同事类(Colleague):定义了各个同事对象执行的操作。它不知道其他同事类,但知道中介者对象。
class Colleague {
protected:
Mediator* mediator;
public:
Colleague(Mediator* m) : mediator(m) {}
virtual void send(const std::string& message) = 0;
virtual void receive(const std::string& message) = 0;
};
- 具体同事类(Concrete Colleague):实现同事类,它的行为由中介者对象协调。
// 具体同事类A
class ConcreteColleagueA : public Colleague {
public:
ConcreteColleagueA(Mediator* m) : Colleague(m) {}
void send(const std::string& message) override {
mediator->send(message, this);
}
void receive(const std::string& message) override {
std::cout << "Colleague A got message: " << message << std::endl;
}
};
// 具体同事类B
class ConcreteColleagueB : public Colleague {
public:
ConcreteColleagueB(Mediator* m) : Colleague(m) {}
void send(const std::string& message) override {
mediator->send(message, this);
}
void receive(const std::string& message) override {
std::cout << "Colleague B got message: " << message << std::endl;
}
};
- 测试
int main() {
ConcreteMediator mediator;
ConcreteColleagueA colleagueA(&mediator);
ConcreteColleagueB colleagueB(&mediator);
mediator.setColleagueA(&colleagueA);
mediator.setColleagueB(&colleagueB);
colleagueA.send("Hello, World!");
colleagueB.send("Hi there!");
return 0;
}
- 结果
Colleague B got message: Hello, World!
Colleague A got message: Hi there!