设计模式_21 中介者模式
21 中介者模式
21.1 概念
定义一个中介角色来封装一系列对象之间的交互,使原有对象之间耦合松散,且可独立的改变他们之间的交互。
多个类之间互相关联,呈现复杂网状结构,过度耦合。引入中介者模式,将类之间关系变为星型结构。任何一个类的变动只会影响类本身和中介者。
21.2 结构
抽象中介者角色:定义了中介者的接口,提供了同事对象注册与转发同事对象信息的抽象方法。
具体中介者角色:实现中介者接口,定义一个list来管理同事对象,协调各个同事角色之间的交互关系。
抽象同事类角色:定义了同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。
具体同事类角色:实现抽象同事类角色,当需要与其他同事对象交互时,由中介者对象负责后续的交互。
21.3 实现
21.3.1 UML图
21.3.2 代码
MediatorAndPerson.h:
#ifndef _MEDIATORANDPERSON_H_
#define _MEDIATORANDPERSON_H_
#include<iostream>
#include<string>
#include<list>
using namespace std;
class Person;
class Tenant;
class HouseHolder;
class Mediator {
public:
virtual void constactTenant(string message, Tenant* tenant) = 0;
virtual void constactHouseHolder(string message, HouseHolder* houseHolder) = 0;
};
class ConcreteMediator : public Mediator {
private:
list<Tenant*> tenants;
list<HouseHolder*> houseHolders;
public:
void addHouseHolder(HouseHolder* houseHolder);
void deleteHouseHolder(HouseHolder* houseHolder);
void addTenant(Tenant* tenant);
void deleteTenant(Tenant* tenant);
void constactTenant(string message, Tenant * tenant);
void constactHouseHolder(string message, HouseHolder* houseHolder);
};
class Person {
protected:
string name;
ConcreteMediator* mediator;
public:
Person(string name, ConcreteMediator* mediator);
};
class Tenant : public Person {
public:
Tenant(string name, ConcreteMediator* mediator);
void constact(string message);
void getMessage(string message);
virtual ~Tenant();
};
class HouseHolder : public Person {
public:
HouseHolder(string name, ConcreteMediator* mediator);
void constact(string message);
void getMessage(string message);
virtual ~HouseHolder();
};
#endif
MediatorAndPerson.cpp:
#include"MediatorAndPsrson.h"
//中介类
void ConcreteMediator::addHouseHolder(HouseHolder* houseHolder) {
houseHolders.push_back(houseHolder);
}
void ConcreteMediator::deleteHouseHolder(HouseHolder* houseHolder) {
houseHolders.remove(houseHolder);
}
void ConcreteMediator::addTenant(Tenant* tenant) {
tenants.push_back(tenant);
}
void ConcreteMediator::deleteTenant(Tenant* tenant) {
tenants.remove(tenant);
}
void ConcreteMediator::constactTenant(string message, Tenant* tenant) {
for (auto it : this->houseHolders) {
(*it).getMessage(message);
}
}
void ConcreteMediator::constactHouseHolder(string message, HouseHolder* houseHolder) {
for (auto it : this->tenants) {
(*it).getMessage(message);
}
}
//同事类
Person::Person(string name, ConcreteMediator* mediator) {
this->name = name;
this->mediator = mediator;
}
//租户类
Tenant::Tenant(string name, ConcreteMediator* mediator) : Person(name, mediator) {
mediator->addTenant(this);
}
void Tenant::constact(string message) {
this->mediator->constactTenant(this->name+"的需求为:"+message, this);
}
void Tenant::getMessage(string message) {
cout << this->name << "收到消息:\n" << message << endl <<endl;
}
Tenant::~Tenant() {
this->mediator->deleteTenant(this);
}
//房屋拥有者类
HouseHolder::HouseHolder(string name, ConcreteMediator* mediator) : Person(name, mediator) {
mediator->addHouseHolder(this);
}
void HouseHolder::constact(string message) {
this->mediator->constactHouseHolder(this->name + "的需求为:" + message, this);
}
void HouseHolder::getMessage(string message) {
cout <<this->name <<"收到消息:\n" << message << endl << endl;
}
HouseHolder::~HouseHolder() {
this->mediator->deleteHouseHolder(this);
}
main.cpp:
#include"MediatorAndPsrson.h"
int main() {
ConcreteMediator* mediator = new ConcreteMediator();
Tenant* tenant1 = new Tenant("租房者1", mediator);
Tenant* tenant2 = new Tenant("租房者2", mediator);
HouseHolder* houseHolder1 = new HouseHolder("房主1", mediator);
HouseHolder* houseHolder2 = new HouseHolder("房主2", mediator);
tenant1->constact("需要一个一室的房子");
houseHolder2->constact("有一个三室两厅的房子");
return 0;
}
21.4 优缺点
21.4.1 优点
松散耦合。把多个同事对象之间的交互封装到中介者对象里,从而使得同事对象之间耦合松散,使得同事对象可以独立变化和复用。
集中控制交互。多个同事对象的交互被封装在中介者对象里统一管理,使得交互行为发生变化时只需要修改中介对象即可。
一对多的关联转变为一对一的关联。使得关系更加易于理解。
21.4.2 缺点
同事类太多时,中介者会变得很庞大,难以维护。
21.5 使用场景
系统中存在复杂的引用关系,系统结构混乱且难以理解。
当想创建一个运行于多个类之间的对象,又不想生成新的子类时。