定义一个对象来封装一系列对象的交互。中介者模式使各对象之间不需要显式地相互引用,从而使其 耦合松散,而且 让你可以独立地改变它们之间的交互。
模式优点
- 简化了对象之间的交互,它用中介者和同事的一对多交互代替了原来同事之间的多对多交互,将原本难以理解的网状结构转换成相对简单的星型结构
- 可将各同事对象解耦
- 可以减少子类生成,中介者模式将原本分布于多个对象间的行为集中在一起,改变这些行为只需生成新的中介者子类即可,这使得各个同事类可被重用,无须直接对同事类进行扩展
模式缺点
- 在具体中介者类中包含了大量的同事之间的交互细节,可能会导致具体中介者类非常复杂,使得系统难以维护
适用环境
- 系统中对象之间存在复杂的引用关系,系统结构混乱且难以理解
- 一个对象由于引用了其他很多对象并且直接和这些对象通信,导致难以复用该对象
- 想通过一个中间类来封装多个类中的行为,又不想生成太多的子类
中介者模式代码
/*
* @ Description: C++ Design Patterns___Mediator
* @ version: v1.0
* @ Author: WeissxJ
*/
#include <iostream>
#include <vector>
#include <string>
class Mediator;
class Colleague
{
public:
Colleague(Mediator *const m, const unsigned int i) : mediator(m), id(i) {}
virtual ~Colleague() {}
unsigned int getID()
{
return id;
}
virtual void send(std::string) = 0;
virtual void receive(std::string) = 0;
protected:
Mediator *mediator;
unsigned int id;
};
class ConcreteColleague : public Colleague
{
public:
ConcreteColleague(Mediator *const m, const unsigned int i) : Colleague(m, i) {}
~ConcreteColleague() {}
void send(std::string msg);
void receive(std::string msg)
{
std::cout << "Message '" << msg << "' received by Colleague " << id << std::endl;
}
};
class Mediator
{
public:
virtual ~Mediator() {}
virtual void add(Colleague *const c) = 0;
virtual void distribute(Colleague *const sender, std::string msg) = 0;
protected:
Mediator() {}
};
class ConcreteMediator : public Mediator
{
public:
~ConcreteMediator()
{
for (unsigned int i = 0; i < colleagues.size(); i++)
{
delete colleagues[i];
}
colleagues.clear();
}
void add(Colleague *const c)
{
colleagues.push_back(c);
}
void distribute(Colleague *const sender, std::string msg)
{
for (unsigned int i = 0; i < colleagues.size(); i++)
{
if (colleagues.at(i)->getID() != sender->getID())
{
colleagues.at(i)->receive(msg);
}
}
}
private:
std::vector<Colleague *> colleagues;
};
void ConcreteColleague::send(std::string msg)
{
std::cout << "Message '" << msg << "' sent by Colleague " << id << std::endl;
mediator->distribute(this, msg);
}
int main()
{
Mediator *mediator = new ConcreteMediator();
Colleague *c1 = new ConcreteColleague(mediator, 1);
Colleague *c2 = new ConcreteColleague(mediator, 2);
Colleague *c3 = new ConcreteColleague(mediator, 3);
mediator->add(c1);
mediator->add(c2);
mediator->add(c3);
c1->send("Hi!");
c3->send("Hello!");
delete mediator;
return 0;
}