本文先以抽象的方式来实现中介者模式,然后用房子的例子来实例化抽象模式的实现。
以租房为例子,如果没有房屋中介,那么房客要自己找房东,而房东也要自己找房客,非常不方便。有了房屋中介机构就方便了,房东可以把要出租的房屋信息放到中介机构,而房客可以去中介机构咨询。在软件中,就是多个对象之间需要通信,如果没有中介,对象就需要知道其他对象,最坏情况下,可能需要知道所有其他对象,而有了中介对象就方便多了,对象只需与中介对象通信,而不用知道其他的对象。
意图:
用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
适用性:
一组对象以定义良好但是复杂的方式进行通信。产生的相互依赖关系结构混乱且难以理解。
一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象。
想定制一个分布在多个类中的行为,而又不想生成太多的子类。
Mediator类:抽象中介者,定义了同事对象交互的接口。
ConcreteMediator类:具体中介者对象,实现抽象类中的方法,此具体中介者对象需要知道所有具体同事类,并从具体同事接受消息,向具体同事对象发送命令。
Colleague类:抽象同事类。
ConcreteColleague类:具体同事类,实现抽象同事类中的方法。每一个同时类需要知道中介者对象;每个具体同事类只需要了解自己的行为,而不需要了解其他同事类的情况。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Mediator;
class Colleague
{
public:
Colleague(Mediator* pMediator) :m_pMediator(pMediator){}
virtual void SendMsg(string message) {};
virtual void GetMsg(string message) {};
protected:
Mediator* m_pMediator;
};
class Mediator
{
public:
virtual void Send(string message, Colleague *pColleague) {}
virtual void set(Colleague *p1, Colleague *p2) = 0;
};
class ConcreteColleague1:public Colleague
{
public:
ConcreteColleague1(Mediator* pMediator) : Colleague(pMediator){}
void SendMsg(string message)
{
m_pMediator->Send(message, this);
}
void GetMsg(string message)
{
cout << "ConcreteColleague2收到来自ConcreteColleague1的消息:" << message << endl;
}
};
class ConcreteColleague2 :public Colleague
{
public:
ConcreteColleague2(Mediator* pMediator) : Colleague(pMediator){}
void SendMsg(string message)
{
m_pMediator->Send(message, this);
}
void GetMsg(string message)
{
cout << "ConcreteColleague1收到来自ConcreteColleague2的消息:" << message<<endl;
}
};
class ConcreteMediator :public Mediator
{
public:
void Send(string message, Colleague *pColleague)
{
if (pColleague == m_p1)
{
m_p2->GetMsg(message);
}
else
{
m_p1->GetMsg(message);
}
}
void set(Colleague *p1, Colleague *p2)
{
m_p1 = p1;
m_p2 = p2;
}
private:
Colleague* m_p1;
Colleague* m_p2;
};
int main()
{
Mediator *mediator = new ConcreteMediator();
Colleague *zhaofeng = new ConcreteColleague1(mediator);
Colleague *fangdong = new ConcreteColleague2(mediator);
mediator->set(zhaofeng, fangdong);
zhaofeng->SendMsg("你还好吗?");
fangdong->SendMsg("我很好!");
return 0;
}
有了上面的抽象化的实现,那我们怎么把这种模式应用到房介的中去呢?看下面的实例化:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Mediator;
//抽象人
class Person
{
protected:
Mediator *m_mediator; //中介
public:
virtual void SetMediator(Mediator *mediator){} //设置中介
virtual void SendMessage(string message) {} //向中介发送信息
virtual void GetMessage(string message) {} //从中介获取信息
};
//抽象中介机构
class Mediator
{
public:
virtual void Send(string message, Person *person) {}
virtual void SetA(Person *A) {} //设置其中一方
virtual void SetB(Person *B) {}
};
//租房者
class Renter : public Person
{
public:
void SetMediator(Mediator *mediator) { m_mediator = mediator; }
void SendMessage(string message) { m_mediator->Send(message, this); }
void GetMessage(string message) { cout << "租房者收到信息" << message; }
};
//房东
class Landlord : public Person
{
public:
void SetMediator(Mediator *mediator) { m_mediator = mediator; }
void SendMessage(string message) { m_mediator->Send(message, this); }
void GetMessage(string message) { cout << "房东收到信息:" << message; }
};
//房屋中介
class HouseMediator : public Mediator
{
private:
Person *m_A; //租房者
Person *m_B; //房东
public:
HouseMediator() : m_A(0), m_B(0) {}
void SetA(Person *A) { m_A = A; }
void SetB(Person *B) { m_B = B; }
void Send(string message, Person *person)
{
if (person == m_A) //租房者给房东发信息
m_B->GetMessage(message); //房东收到信息
else
m_A->GetMessage(message);
}
};
//测试案例
int main()
{
Mediator *mediator = new HouseMediator();
Person *person1 = new Renter(); //租房者
Person *person2 = new Landlord(); //房东
mediator->SetA(person1);
mediator->SetB(person2);
person1->SetMediator(mediator);
person2->SetMediator(mediator);
person1->SendMessage("我想在南京路附近租套房子,价格800元一个月\n");
person2->SendMessage("出租房子:南京路100号,70平米,1000元一个月\n");
delete person1; delete person2; delete mediator;
return 0;
}
总结:
适用性:
一组对象以定义良好但是复杂的方式进行通信。产生的相互依赖关系结构混乱且难以理解。
一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象。
想定制一个分布在多个类中的行为,而又不想生成太多的子类。
优缺点:
使用中介者模式的优点:
降低了系统对象之间的耦合性,使得对象易于独立的被复用。
提高系统的灵活性,使得系统易于扩展和维护。
使用中介者模式的缺点:
“中介“承担了较多的责任,所以一旦这个中介对象出现了问题,那么整个系统就会受到重大的影响。