16 中介者(Mediator)模式
中介者模式
1.1 分类
(对象)行为型
1.2 提出问题
实现一个机场的起飞管理系统,如果由驾驶员们讨论谁先飞,后果可能是灾难性的。
1.3 解决方案
用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使得其耦合松散。
1.4 实现类图
- 组件(Component)是各种包含业务逻辑的类。每个组件都有一个指向中介者的引用,可通过将其连接到不同的中介者以使其能在其他程序中复用。
- 中介者(Mediator)接口声明了与组件交流的方法,但通常仅包括一个通知方法。
- 具体中介者(Concrete Mediator)封装了多种组件间的关系。 具体中介者通常会保存所有组件的引用并对其进行管理。
- 组件并不知道其他组件的情况。如果组件内发生了重要事件, 它只能通知中介者。中介者收到通知后能轻易地确定发送者。
1.5 示例代码
#include <iostream>
#include <string>
class Staff;
//Mediator Interface
class ControlTower {
public:
virtual void notify(Staff* sender, std::string event) const = 0;
};
class Staff {
protected:
std::string m_name;
ControlTower* m_controlTower;
public:
Staff(std::string name, ControlTower* controlTower = nullptr)
:m_name(name), m_controlTower(controlTower) {}
std::string name() {
return m_name;
}
void setMediator(ControlTower* controlTower) {
m_controlTower = controlTower;
}
};
class Pilot : public Staff {
public:
Pilot(std::string name):Staff(name){}
void takeOff() {
std::cout << name() + ":请求起飞。\n";
m_controlTower->notify(this, "起飞请求");
}
void copy() {
std::cout << name() + ":收到。\n";
//m_controlTower->notify(this, "收到");
}
};
class GroundGrew : public Staff {
public:
GroundGrew(std::string name) :Staff(name) {}
void maintainance() {
std::cout << name() + ":请求维护。\n";
m_controlTower->notify(this, "请求维护");
}
void copy() {
std::cout << name() + ":收到。\n";
//m_controlTower->notify(this, "收到");
}
};
class ConcreteControlTower : public ControlTower {
private:
Pilot* m_pilot1;
Pilot* m_pilot2;
Pilot* m_pilot3;
GroundGrew* m_ground1;
public:
ConcreteControlTower(Pilot* p1, Pilot* p2, Pilot* p3, GroundGrew* g1)
:m_pilot1(p1), m_pilot2(p2), m_pilot3(p3),m_ground1(g1) {
m_pilot1->setMediator(this);
m_pilot2->setMediator(this);
m_pilot3->setMediator(this);
m_ground1->setMediator(this);
}
void notify(Staff* sender, std::string event) const override {
std::cout << "控制塔:收到" + sender->name() + event + "。\n";
if (event == "起飞请求") {
m_ground1->copy();
if(sender!= m_pilot1)
m_pilot1->copy();
if (sender != m_pilot2)
m_pilot2->copy();
if (sender != m_pilot3)
m_pilot3->copy();
}
if (event == "请求维护") {
m_pilot1->copy();
m_pilot2->copy();
m_pilot3->copy();
}
}
};
int main()
{
Pilot* p1 = new Pilot("空军1号");
Pilot* p2 = new Pilot("空军2号");
Pilot* p3 = new Pilot("空军3号");
GroundGrew* g1 = new GroundGrew("地勤1");
ConcreteControlTower* controlTower = new ConcreteControlTower(p1, p2, p3, g1);
p1->takeOff();
g1->maintainance();
delete p1;
delete p2;
delete p3;
delete g1;
}
1.6 举个栗子
中介者模式可帮助你减少各种 UI 类(按钮、复选框和文本标签)之间的相互依赖关系。
1.7 总结
1.7.1 优点
- 无需修改实际组件就能增加新的中介者。
- 可以减轻应用中多个组件间的耦合情况。
- 可以更方便地复用各个组件。
1.7.2 缺点
一段时间后,中介者可能会演化成为上帝对象。