中介模式(Mediator Pattern)用来降低多个对象和类之间的通信复杂性。这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护。中介者模式属于行为型模式。
意图
用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显示的互相调用,从而使其耦合松散,而且可以 独立地改变它们之间的交互。
解决问题
对象与对象之间存在大量的关联关系,这样势必会导致系统的结构变得很复杂,同时若一个对象发生改变,我们也需要跟踪与之相关联的对象,同时做出相应的处理。
如何解决
多个类互相耦合形成了网状结构 分离为 星型结构。
优点
1. 降低了类的复杂度,将一对多转换为一对一;
2. 各个类之间解耦;
3. 符合迪米特法则
缺点
中介者会变大, 使得难以维护。
使用场景
1.一组对象以定义良好但是复杂的方式进行通信。产生的相互依赖关系结构混乱且难以理解;
2.一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象;
3.想定制一个分布在多个类中的行为,而又不想生成太多的子类。
注意事项
不应当在职责混乱的时候使用
C++实现
举例: 假设我们开发一个图片处理软件,里面肯定包括很多相关功能,比如说剪切,旋转,滤镜,美化等等,而我们这些功能所要处理的对象是固定的,就是我们所显示的那张图片。但是我们不能把所有的功能罗列到一个tab上,虽然这样处理方便但是不美观。这是我们可以这样子:用一个中介者类负责所有功能的初始化和具体执行,我们需要功能时直接调用中介者类即可。
code:
//中介模式
/*
Mediator类:抽象中介者,定义了同事对象交互的接口
ConcreteMediator类:具体中介对象,实现抽象类中的方法,此具体中介者对象需要知道所有具体同事类,并从具体同事接受消息,向具体同事对象发送命令。
Colleague类:抽象同事类
ConcreteColleague 类: 具体同事类,实现抽象同事类中的具体方法。每一个同事类需要知道中介者对象;每个具体同事类只需要了解自己的行为,而不需要了解其他同事类的情况。
*/
class Colleaguage //抽象同事类
{
string name;
string content;
public:
Colleaguage(string n = "")
:name(n)
{}
string get_name()
{
return name;
}
void set_name(string _name)
{
name = _name;
}
void set_content(string _content)
{
content = _content;
}
string Get_Content()
{
if (content.size() != 0)
return content;
else
return "Copy that";
}
virtual void talk()
{}
};
class Monitor : public Colleaguage
{
public :
Monitor(string n = "")
:Colleaguage(n)
{}
virtual void talk()
{
cout << "班长 "<< get_name()<<"说:"<<Get_Content() << endl;
}
};
class Secretary :public Colleaguage
{
public:
Secretary(string n = "")
:Colleaguage(n)
{}
virtual void talk()
{
cout << "团支书"<< get_name()<<"说 : " << Get_Content()<< endl;
}
};
class StudentA : public Colleaguage
{
public :
StudentA(string n = "")
:Colleaguage(n)
{}
virtual void talk()
{
cout <<"学生 A " <<get_name() << "说:"<<Get_Content()<< endl;
}
};
class StudentB :public Colleaguage
{
public:
StudentB(string n = "")
:Colleaguage(n)
{}
virtual void talk()
{
cout << "学生 B "<<get_name() <<"说:"<<Get_Content() << endl;
}
};
class Mediator //抽象中介
{
public :
vector<Colleaguage*> studentList;
virtual void add_student(Colleaguage* stu)
{
studentList.push_back(stu);
}
virtual void notify(Colleaguage* stu)//公布
{}
};
class QQMediator : public Mediator //具体中介
{
public:
virtual void notify(Colleaguage * stu)
{
stu->talk();
for (size_t i = 0; i < studentList.size(); i++)
{
if (stu != studentList[i])
studentList[i]->talk();
}
}
};
客户端:
int test_Mediator() //中介模式
{
QQMediator qq;
Monitor* stuMonitor = new Monitor("小明");
Secretary* stuSecretary = new Secretary("小丽");
StudentA* stuA = new StudentA("Jack");
StudentB * stuB = new StudentB("Rose");
qq.add_student(stuSecretary);
qq.add_student(stuA);
qq.add_student(stuB);
stuMonitor->set_content("明天放假!");
qq.notify(stuMonitor);
delete stuMonitor;
delete stuSecretary;
delete stuA;
delete stuB;
system("pause");
return 0 ;
}
结果:
总结
我在看中介者模式时,第一眼就感觉中介者模式和外观模式超级像。外观模式与中介者模式的不同之处在于它是对一个对象子系统进行抽象,从而提供了一个更为方便的接口;外观模式的协议是单向的,即外观模式向子系统提出请求,但反过来则不行;而对于中介者模式,是进行多个对象之间的协作,通信是多向的。