中介者模式
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 缺點
一段時間后,中介者可能會演化成為上帝對象。