将一个系统分割成许多对象通常可以增加其可复用性,但是对象之间相互连接的激增又会降低其可复用性。因为大量的连接使得一个对象不可能在没有其他对象的支持下工作,系统表现为一个不可分割的整体,所以,对系统的行为进行任何较大的改动就十分困难了。
中介者模式(Mediator):
用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变他们之间的交互。
例子:
你到了一个公司,尤其是大公司,项目上有各部门配合的时候,你不可能一下子熟悉各个部门的同事,当你有什么需求的时候,最好的选择就是找一个“中介者”帮助你去联系你需要联系的同事(放出《大话设计模式》中的结构图↓↓↓)。
代码如下:
#include <iostream>
#include <string>
using namespace std;
class Colleague;
//抽象中介者类
class Mediator
{
public:
Mediator() {}
virtual ~Mediator() {}
//得到同事对象和发送的消息
virtual void Send(string msg, Colleague* col) = 0;
};
//抽象同事类
class Colleague
{
protected:
Mediator* mediator;
public:
Colleague(Mediator* med):mediator(med) {}
virtual ~Colleague() {}
virtual void Send(string message) = 0;
virtual void Notify(string msg) = 0;
};
//具体同事类
class ConcreteColleague :public Colleague
{
public:
ConcreteColleague(Mediator* med) :Colleague(med) {}
~ConcreteColleague() {}
void Send(string message)
{
//消息是由中介者发出去的
mediator->Send(message, this);
}
void Notify(string msg)
{
cout << "ConcreteColleague One Get Msg: " << msg << endl;
}
};
class ConcreteColleague2 :public Colleague
{
public:
ConcreteColleague2(Mediator* med) :Colleague(med) {}
~ConcreteColleague2() {}
void Send(string message)
{
//消息是由中介者发出去的
mediator->Send(message, this);
}
void Notify(string msg)
{
cout << "ConcreteColleague Two Get Msg: " << msg << endl;
}
};
//具体中介者类
class ConcreteMediator :public Mediator
{
private:
Colleague* one;
Colleague* two;
public:
ConcreteMediator() {}
~ConcreteMediator() {}
void SetColleatueOne(Colleague* o)
{
one = o;
}
void SetCollegueTwo(Colleague* t)
{
two = t;
}
// 通过 Mediator 继承
virtual void Send(string msg, Colleague* col) override
{
if (col == one)
{
two->Notify(msg);
}
else
one->Notify(msg);
}
};
int main()
{
ConcreteMediator* m = new ConcreteMediator();
//让两个同事认识中介者
Colleague* c1 = new ConcreteColleague(m);
Colleague* c2 = new ConcreteColleague2(m);
//让中介者认识各个具体同事类对象
m->SetColleatueOne(c1);
m->SetCollegueTwo(c2);
c1->Send("How's day?");
c2->Send("Beautiful day");
delete m;
delete c1;
delete c2;
getchar();
return 0;
}
中介者模式的优点:
Mediator的出现减少了各个Collegue的耦合,使得可以独立地改变和复用各个Collegue类和Mediator。
由于把对象如何协作进行了抽象,将中介作为独立地一个概念并将其封装在一个对象中,这样关注的对象就从对象各自本身的行为转移到他们之间的交互上来,也就是站在一个更宏观的角度去看待系统。
但是呢,中介者模式也不是可以随便用的。由于ConcreteMediator控制了集中化,于是就把交互复杂性变成了中介者的复杂性,这就使得中介者会变得比任何一个ConcreteCollegue都复杂。所以,在系统中出现了“多对多”交互复杂的对象群时,不要急于使用中介者模式,而要先反思你的系统在设计上是不是合理。
实际上,任何设计模式都有它独特的使用场景,在使用时,我们需要多多考虑实际需求,切勿为了设计而设计。