一、简介
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