中介者模式(Mediator)
-
介绍:定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互
中介者模式又叫调停模式,它是迪米特法则的典型应用。 -
如果一个系统里各个对象之间存在多对多的相互关系,可以将对象之间的一些交互行为从各个对象中分离出来,集中封装在一个中介者对象中,使其耦合松散,并由中介者统一协调。通过中介者,对象之间的多对多关系就简化了相对更简单的一对多关系。
-
优点:
类之间各司其职,符合迪米特法则。
降低了对象之间的耦合性,使得对象易于独立地被复用。
将对象间的一对多关联转变为一对一的关联,提高系统的灵活性,使得系统易于维护和扩展。 -
缺点:中介者模式将原本多个对象直接的相互依赖变成了中介者和多个同事类的依赖关系。当同事类越多时,中介者就会越臃肿,变得复杂且难以维护。
-
主要角色
抽象中介者(Mediator)角色:它是中介者的接口,提供了同事对象注册与转发同事对象信息的抽象方法。
具体中介者(Concrete Mediator)角色:实现中介者接口,定义一个 List 来管理同事对象,协调各个同事角色之间的交互关系,因此它依赖于同事角色。
抽象同事类(Colleague)角色:定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。
具体同事类(Concrete Colleague)角色:是抽象同事类的实现者,当需要与其他同事对象交互时,由中介者对象负责后续的交互。
#include "iostream"
#include "string"
#include "vector"
using namespace std;
enum PERSON_TYPE
{
NONE,
LANDLORD, //房东
TENANT //租客
};
//抽象同事类
class Colleague;
//抽象中介者
class Mediator
{
public:
Mediator(){}
//声明抽象方法
virtual void Operation(Colleague*) = 0;
//声明注册方法
virtual void RegisterMethod(Colleague*) = 0;
};
//抽象同事类
class Colleague
{
public:
Colleague(){}
void SetMediator(Mediator * med)
{
mediator = med;
}
Mediator * GetMediator()
{
return mediator;
}
void SetPersonType(PERSON_TYPE p)
{
personType = p;
}
PERSON_TYPE GetPersonType()
{
return personType;
}
virtual void ask() = 0;
virtual void answer() = 0;
private:
PERSON_TYPE personType;
Mediator *mediator;
};
class Agency;
// 具体同事类:房东
class Landlord :public Colleague
{
public:
Landlord(){
name = "none";
price = 0;
address = "none";
phoneNumber = "none";
SetPersonType(NONE);
}
Landlord(string iName, int iPrice, string iAddress, string iPhoneNum)
{
name = iName;
price = iPrice;
address = iAddress;
phoneNumber = iPhoneNum;
SetPersonType(LANDLORD);
}
void ask()
{
printf("房东%s查看租客信息:\n", name.c_str());
GetMediator()->Operation(this);
}
void answer()
{
printf("房东姓名:%s, 房租:%d, 地址:%s, 联系电话:%s\n",
name.c_str(), price, address.c_str(), phoneNumber.c_str());
}
private:
string name;
int price;
string address;
string phoneNumber;
};
// 具体同事类:租客
class Tenant :public Colleague
{
public:
Tenant()
{
name = "none";
SetPersonType(NONE);
}
Tenant(string strname)
{
name = strname;
SetPersonType(TENANT);
}
void ask()
{
printf("租客%s询问房东信息\n", name.c_str());
GetMediator()->Operation(this);
}
void answer()
{
printf("租客姓名:%s\n", name.c_str());
}
private:
string name;
};
//具体中介者
class Agency : public Mediator
{
public:
Agency(){}
void RegisterMethod(Colleague* person)
{
switch (person->GetPersonType())
{
case LANDLORD:
landlordList.push_back((Landlord*)person);
break;
case TENANT:
tenantList.push_back((Tenant*)person);
break;
default:
break;
}
}
void Operation(Colleague* person)
{
switch (person->GetPersonType())
{
case LANDLORD:
for (int i = 0; i < (int)tenantList.size(); ++i)
{
tenantList[i]->answer();
}
break;
case TENANT:
for (int i = 0; i < (int)landlordList.size(); ++i)
{
landlordList[i]->answer();
}
break;
default:
break;
}
}
private:
vector<Landlord*>landlordList;
vector<Tenant*>tenantList;
};
int main()
{
//创建代理中介
Agency * mediator = new Agency;
//创建房东
Landlord *Fd_1 = new Landlord("老A", 3000, "北京海淀区", "110");
Landlord *Fd_2 = new Landlord("老B", 4000, "北京西城区", "120");
Landlord *Fd_3 = new Landlord("老C", 5000, "北京朝阳区", "119");
Fd_1->SetMediator(mediator);
Fd_2->SetMediator(mediator);
Fd_3->SetMediator(mediator);
//中介登记
mediator->RegisterMethod(Fd_1);
mediator->RegisterMethod(Fd_2);
mediator->RegisterMethod(Fd_3);
//创建租客
Tenant *T1 = new Tenant("小D");
Tenant *T2 = new Tenant("小E");
T1->SetMediator(mediator);
T2->SetMediator(mediator);
mediator->RegisterMethod(T1);
mediator->RegisterMethod(T2);
T1->ask();
cout << endl;
Fd_1->ask();
system("pause");
return 1;
}
运行结果:
租客小D询问房东信息
房东姓名:老A, 房租:3000, 地址:北京海淀区, 联系电话:110
房东姓名:老B, 房租:4000, 地址:北京西城区, 联系电话:120
房东姓名:老C, 房租:5000, 地址:北京朝阳区, 联系电话:119
房东老A查看租客信息:
租客姓名:小D
租客姓名:小E
请按任意键继续. . .