该模式会限制对象之间的直接交互,迫使它们通过一个中介者对象进行合作。
像是现实中的房东和租客之间可以是链家等中介,这样某房东可以通过中介获取所有租客信息,某租客也可以通过中介获取所有房东信息。没有中介,某房东只能一个一个租客去问,比较混乱。
实例
Component.h
#ifndef COMPONENT_H_
#define COMPONENT_H_
#include "Mediator.h"
#include <cstdio>
#include <string>
enum PERSON_TYPE {
kUnknown,
kLandlord,
kTenant,
};
// 组件基类
class Colleague {
public:
void set_mediator(Mediator *m) {
mediator_ = m;
}
Mediator* get_mediator() {
return mediator_;
}
void set_personType(PERSON_TYPE pt) {
person_type_ = pt;
}
PERSON_TYPE get_person_type() {
return person_type_;
}
virtual void ask() = 0;
virtual void answer() = 0;
private:
Mediator* mediator_;
PERSON_TYPE person_type_;
};
// 具体组件1: 房东
class Landlord : public Colleague {
public:
Landlord() {
name_ = "unknown";
price_ = -1;
address_ = "unknown";
phone_number_ = "unknown";
set_personType(kUnknown);
}
Landlord(std::string name, int price, std::string address, std::string phone_number) {
name_ = name;
price_ = price;
address_ = address;
phone_number_ = phone_number;
set_personType(kLandlord);
}
void answer() override {
printf("房东姓名:%s 房租:%d 地址:%s 电话:%s\n", name_.c_str(), price_, address_.c_str(), phone_number_.c_str());
}
void ask() override {
printf("房东%s查看租客信息: \n", name_.c_str());
this->get_mediator()->operation(this);
}
private:
std::string name_;
int price_;
std::string address_;
std::string phone_number_;
};
// 具体组件2: 租客
class Tenant : public Colleague {
public:
Tenant() {
name_ = "unknown";
}
explicit Tenant(std::string name) {
name_ = name;
set_personType(kTenant);
}
void ask() {
printf("租客%s询问房东信息:\n", name_.c_str());
this->get_mediator()->operation(this);
}
void answer() {
printf("租客姓名: %s\n", name_.c_str());
}
private:
std::string name_;
};
#endif // COMPONENT_H_
ConcreteMediator.h
#ifndef CONCRETE_MEDIATOR_H_
#define CONCRETE_MEDIATOR_H_
#include <vector>
#include <string>
#include "Component.h"
#include "Mediator.h"
// 具体中介类: 房产中介
class Agency : public Mediator {
public:
void registerMethod(Colleague* person) override {
switch (person->get_person_type()) {
case kLandlord:
landlord_list_.push_back(reinterpret_cast<Landlord*>(person));
break;
case kTenant:
tenant_list_.push_back(reinterpret_cast<Tenant*>(person));
break;
default:
printf("wrong person\n");
}
}
void operation(Colleague* person) {
switch (person->get_person_type()) {
case kLandlord:
for (int i = 0; i < tenant_list_.size(); i++) {
tenant_list_[i]->answer();
}
break;
case kTenant:
for (int i = 0; i < landlord_list_.size(); i++) {
landlord_list_[i]->answer();
}
break;
default:
break;
}
}
private:
std::vector<Landlord*> landlord_list_;
std::vector<Tenant*> tenant_list_;
};
#endif // CONCRETE_MEDIATOR_H_
Mediator.h
#ifndef MEDIATOR_H_
#define MEDIATOR_H_
#include <string>
class Colleague;
// 抽象中介者
class Mediator {
public:
// 声明抽象方法
virtual void registerMethod(Colleague*) = 0;
// 声明抽象方法
virtual void operation(Colleague*) = 0;
};
#endif // MEDIATOR_H_
main.cpp
#include <iostream>
#include "ConcreteMediator.h"
#include "Component.h"
int main() {
// 房产中介
Agency *mediator = new Agency();
// 三位房东
Landlord *l1 = new Landlord("张三", 1820, "天津", "1333");
Landlord *l2 = new Landlord("李四", 2311, "北京", "1555");
Landlord *l3 = new Landlord("王五", 3422, "河北", "1777");
l1->set_mediator(mediator);
l2->set_mediator(mediator);
l3->set_mediator(mediator);
mediator->registerMethod(l1);
mediator->registerMethod(l2);
mediator->registerMethod(l3);
// 两位租客
Tenant *t1 = new Tenant("Zhang");
Tenant *t2 = new Tenant("Yang");
t1->set_mediator(mediator);
t2->set_mediator(mediator);
mediator->registerMethod(t1);
mediator->registerMethod(t2);
// 业务逻辑
t1->ask();
std::cout << std::endl;
l1->ask();
delete mediator;
delete l1;
delete l2;
delete l3;
delete t1;
delete t2;
}
编译运行:
$g++ -g main.cpp -o mediator -std=c++11
$./mediator
租客Zhang询问房东信息:
房东姓名:张三 房租:1820 地址:天津 电话:1333
房东姓名:李四 房租:2311 地址:北京 电话:1555
房东姓名:王五 房租:3422 地址:河北 电话:1777
房东张三查看租客信息:
租客姓名: Zhang
租客姓名: Yang
代理模式PK中介者模式:
- 代理模式是1对1,一个代理只能代表一个对象。中介者模式则是多对多,比如上面的多个房东对应多个租客。
- 代理模式只能代理一方,比如Proxy代理A,则B可以通过Proxy访问A,但是A不能通过Proxy访问B,因为Proxy和B没关系。中介者Mediator,A可以通过Mediator访问B,B也可以通过Mediator访问A。