一、簡介
1. 定義
用一箇中介對象來封裝一系列的對象交互。中介者使各對象不需要顯式地相互引用,從而使其耦合鬆散,而且可以獨立地改變它們之間的交互。
2. 應用場景
適用於系統中大量的對象需要相互的依賴,並且彼此間的依賴關係複雜混亂,此時在重構過程中,可以用一箇中間類來管理這些對象之間的依賴關係。
3.優缺點
優點:
將多個互相依賴的類進行解耦,使得這些有交互的對象鬆耦合;
增加交互對象時,只需要在中介類中進行修改即可,不需要變動其他的對象實現;
缺點:
中介類可能會變得複雜,甚至會發展到功能龐大,違反類的單一職責。
4. 類圖
二、 代碼示例
1. 場景簡介
在組隊槍戰遊戲中,突擊小隊需要通過通訊設備來完成戰術的安排與實施,隊長主要負責下達命令,隊員根據戰況請求支援。
#ifndef MEDIATOR_H #define MEDIATOR_H #include <QString> #include <QDebug> #include <QMap> class IMediator; class IUser { public: IUser(QString name) : m_name(name) {}; virtual ~IUser() {}; inline QString name() { return m_name; }; virtual void send(QString msg, IMediator *mediator) = 0; virtual void notify(QString msg) = 0; private: QString m_name; }; class IMediator { public: IMediator() {}; virtual ~IMediator() {}; virtual void registeUser(IUser *user) { QString name = user->name(); if (!m_userMap.contains(name)) { m_userMap.insert(name, user); } }; virtual void unregisterUser(IUser *user) { m_userMap.remove(user->name()); }; virtual void sendMsg(QString msg, IUser *sender) = 0; protected: QMap<QString, IUser*> m_userMap; }; class GameMediator : public IMediator { public: GameMediator() {}; virtual ~GameMediator() {}; virtual void sendMsg(QString msg, IUser *sender) { foreach (IUser* user, m_userMap) { if (user->name() != sender->name()) { user->notify(msg); } } }; }; class UserImp : public IUser { public: UserImp(QString name) : IUser(name) {}; virtual ~UserImp() {}; virtual void send(QString msg, IMediator *mediator) { if (nullptr != mediator) { mediator->sendMsg(msg, this); } }; virtual void notify(QString msg) { qDebug() << name() << "receive msg: " << msg; }; }; #if 1 #define FREE_OBJ(obj) if (nullptr != (obj)){delete (obj); (obj) = nullptr;} void main() { IMediator *mediator = new GameMediator; UserImp *captain = new UserImp("Game Captain"); UserImp *playerA = new UserImp("XiaoMing"); UserImp *playerB = new UserImp("XiaoQiang"); mediator->registeUser(captain); mediator->registeUser(playerA); mediator->registeUser(playerB); captain->send("Ready?", mediator); playerA->send("Help!", mediator); FREE_OBJ(mediator); FREE_OBJ(captain); FREE_OBJ(playerA); FREE_OBJ(playerB); getchar(); } #endif // 1 #endif // !MEDIATOR_H