[设计模式]行为模式-中介者(C++描述)
second60 20180531
1. 中介者定义
中介者模式提供对象间的交互和通讯封装在一个类中,各个对象间的通信不必显势去声明和引用,大大降低了系统的复杂性。
在面向对象的软件设计与开发过程中,根据单一职责原则,尽量将对象细化,使其只负责或呈现单一的职责,将行为分布到各个对象中。
对于一个模块或系统,可能由很多对象构成,而且这些对象之间存在相互的引用,在最坏的情况下,每一个对象都知道其他所有对象,这复杂了对象之间的联系。虽然将一个系统分割成许多对象通常可以增强复用性,但是对象间相互连接的激增又会降低其可复用性,大量相互连接使得一个对象似乎不太可能在没有其他对象的支持下工作,系统表现为一个不可分割的整体,对系统的行为进行任何较大的改运都会十分困难。
结果是不得不定义大量的子类以定制系统的行为。因此,为了减少对象两两之间的复杂的引用关系,使之成为一个松耦合的系统,我们需要使用中介者模式。
2. 中介者模式结构图
分析:
1. 中介者父类Mediator: 中介者定义一个接口用于各Colleague对象通信。
2. 具体中介者:通过协调各同事对象实现协作行为,了解并维护它的各同事。
3. 抽事同事类:定义同事类接口,定义各同事公有方法
4. 具体同事类:实现抽象同事方法。每一个同时需要知道中介者对象;每个具体同事类只需要了解自已的行为。每一个同事对象在需与其他同事通信时,与它的中介者通信。
3. 代码
#include <string>
using namespace std;
class Mediator;
// 同事父类
class Colleage
{
public:
virtual ~Colleage(){}
virtual void Action() = 0;
virtual void SetState(const string& str) = 0;
virtual string GetState() = 0;
protected:
Colleage(){}
Colleage(Mediator* mdt)
{
_mdt = mdt;
}
Mediator* _mdt;
};
class ConcreteColleageA: public Colleage
{
public:
~ConcreteColleageA(){}
void Action(){_mdt->DoActionFromAtoB();}
void SetState(const string& str){_std = std;}
string GetState(){return _sdt;}
ConcreteColleageA(){}
ConcreteColleageA(Mediator* mdt):Colleage(mdt){}
private:
string _sdt;
};
class ConcreteColleageB: public Colleage
{
public:
~ConcreteColleageB(){}
void Action(){_mdt->DoActionFromBtoA();}
void SetState(const string& str){_std = std;}
string GetState(){return _sdt;}
ConcreteColleageB(){}
ConcreteColleageB(Mediator* mdt):Colleage(mdt){}
private:
string _sdt;
};
// 中介者父类
class Mediator
{
public:
virtual ~Mediator(){}
virtual void DoActionFromAtoB() = 0;
virtual void DoActionFromBtoA() = 0;
protected:
Mediator(){}
};
class ConcreteMediator: public Mediator
{
public:
ConcreteMediator(){}
ConcreteMediator(Colleage* clgA, Colleage* clgB)
{
_clgA = clgA;
_clgB = clgB;
}
~ConcreteMediator(){}
void SetConcreteColleageA(Colleage* clgA){
this->_clgA = clgA;
}
void SetConcreteColleageB(Colleage* clgB){
this->_clgB = clgB;
}
Colleage* GetConcreteColleageA(){return _clgA;}
Colleage* GetConcreteColleageB(){return _clgB;}
void IntroColleage(Colleage* clgA, Colleage* clgB){
_clgA = clgA;
_clgB = _clgB;
}
void DoActionFromAtoB(){
_clgB->SetState(_clgA->GetState());
}
void DoActionFromBtoA(){
_clgA->SetState(_clgB->GetState());
}
private:
Colleage* _clgA;
Colleage* _clgB;
};
int main()
{
ConcreteMediator* m = new ConcreteMediator();
ConcreteColleageA* c1 = new ConcreteColleageA(m);
ConcreteColleageB* c2 = new ConcreteColleageB(m);
m->IntroColleage(c1,c2);
c1->SetState(“old”);
c2->SetState(“old”);
c1->Action();
c2->Action();
c1->SetState(“new”);
c1->Action();
c2->Action();
c2->SetState(“old”);
c2->Action();
c1->Action();
return 0;
}
Mediator是一种很有用且很常用的模式,它通过将对象的通信封装到一个类中,将多对多的通信转化为一对多的通信,降低了系统的复杂性。
还解耦了系统,通过中介者,各个colleage就不必维护各自通信的对象和通信协议,降低了系统的耦合性,mediator和各个Colleage就可以相互独立地修改了。
中介者模式将控制集中,便宜于管理,也正符合OO设计中的每个类的职责单一的原则。
4 使用场景
中介者模式适合于多个对象之间紧密耦合的情况,在类图中出现了蜘蛛网状结构。这有利于把蜘蛛网结构梳理为星型结构,使原本复杂的关系变清晰。
中介者模式也叫调停者模式,一个对象要与N个对象交流时,就非常混乱。如加入一个调度中心,所有的类都和中心交流。
用途:
1. 调度中心
2. MVC模式中的Controller
3. 中介服务。
4. 用在多对多对象复杂关系中,简代成一对多关系
5 优缺点
优点:减少类之间的依赖,把原有的一对多依赖变成一对一依赖,降低耦合性。
缺点:中介者会很大,而且逻辑复杂,原本N个对象直接相互依赖关系转换成中介者和同事依赖关系,同事类越多,中介者越复杂。
6 总结
中介者模式是用途很广的设计模式之一。在MCV模式中,观察者模式相当于是Model和View, 而中介者模式相当于是Controller控制器。