中介者模式
定义:
用一个中介对象来封装一系列的对象交互。中介者使对象不需要显示的相互引用,从而使其耦合松散,而且可以独立的完成改变它们之间的交互。
适用性:
1、 一组对象以定义良好但是复杂的方式进行通信。产生的相互依赖关系结构混乱且难以理解。
2、 一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象。
3、 想定制一个分布在多个类中的行为,而又不想生成太多的子类。
优点:
1、 减少了子类的生成
2、 将colleague类解耦
3、 简化了对象协议
4、 对对象如何协作进行了抽象。
缺点:
控制集中化,使得中介者变得复杂而难以维护。
结构:
实现:
class Mediator;
class Colleague
{
public:
Colleague(string name,Mediator*pMediator):m_name(name),m_pMediator(pMediator)
{}
virtual void SendMessage(string mes) {}
virtual void ReceiveMessage(string mes) {}
string GetName()
{
returnm_name;
}
protected:
string m_name;
Mediator *m_pMediator;
};
class Mediator
{
public:
virtual~Mediator() {}
virtual void SetColleagueA(Colleague *pa)
{ }
virtual void SetColleagueB(Colleague *pb)
{ }
virtual void TransmitMessage(string mes, Colleague *p)
{ }
};
class ConcreteMediator:public Mediator
{
public:
void SetColleagueA(Colleague *pa)
{
m_pColleagueA = pa;
}
void SetColleagueB(Colleague *pb)
{
m_pColleagueB = pb;
}
void TransmitMessage(string mes, Colleague *p)
{
mes = p->GetName() + "\n\r message: " + mes ;
if (p ==m_pColleagueA)
{
m_pColleagueB->ReceiveMessage(mes);
}
else if(p == m_pColleagueB)
{
m_pColleagueA->ReceiveMessage(mes);
}
}
private:
Colleague *m_pColleagueA;
Colleague *m_pColleagueB;
};
class ConcreteColleagueA:public Colleague
{
public:
ConcreteColleagueA(string name,Mediator*pMediator):Colleague(name,pMediator)
{}
void SendMessage(string mes)
{
m_pMediator->TransmitMessage(mes,this);
}
void ReceiveMessage(string mes)
{
cout<<m_name<<" receivemessage from "<<mes<<endl;
}
};
class ConcreteColleagueB:public Colleague
{
public:
ConcreteColleagueB(string name,Mediator*pMediator):Colleague(name,pMediator)
{}
void SendMessage(string mes)
{
m_pMediator->TransmitMessage(mes,this);
}
void ReceiveMessage(string mes)
{
cout<<m_name<<" receivemessage from "<<mes<<endl;
}
};
Mediator *pm = newConcreteMediator();
Colleague *pa = newConcreteColleagueA("colleagueA",pm);
Colleague *pb = newConcreteColleagueB("colleagueB",pm);
pm->SetColleagueA(pa);
pm->SetColleagueB(pb);
pa->SendMessage("hello ,my name is lily");
pb->SendMessage("hello lily ,my name is liming");