#ifndef __MEDIATOR_H__
#define __MEDIATOR_H__
#include <string>
#include <list>
//【说明】
// 中介者是对象的通信中心。当一个对象需要与另一个对象通信时,它不会直接调用另一个对象。
// 相反,它会调用中介者对象,其主要职责是将消息路由到目标对象,它允许开发人员不必管理对象之间的链接。
//【定义】
// 中介者模式(Mediator): 用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
//【角色】
// Colleague(抽象同事类):定义与其他 Colleague 通信的接口。
// ConcreteColleague(具体同事类):实现 Colleague 接口,并通过 Mediator 与其他 Colleague 进行沟通。
// Mediator(抽象中介者):为 Colleague 对象之间的通信定义接口。
// ConcreteMediator(具体中介者):实现 Mediator 接口,并需要了解和维护各个 Colleague 对象,负责协调他们之间的通信。
//【意义】
// 适用场景
// 系统中对象之间存在比较复杂的引用关系,导致它们之间的依赖关系结构混乱而且难以复用该对象。
// 想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。
// 优点:
// 中介者模式简化了对象之间的交互,它用中介者和同事的一对多交互代替了原来同事之间的多对多交互,一对多关系更容易理解、维护和扩展,将原本难以理解的网状结构转换成相对简单的星型结构。
// 中介者模式可将各同事对象解耦。中介者有利于各同事之间的松耦合,可以独立地改变和复用每一个同事和中介者,增加新的中介者和新的同事类都比较方便,更好地符合“开闭原则”。
// 可以减少子类生成,中介者将原本分布于多个对象间的行为集中在一起,改变这些行为只需生成新的中介者子类即可,这使各个同事类可被重用,无须对同事类进行扩展。
// 缺点:
// 如果存在大量同事之间的交互,中介者将会变得非常复杂,使得系统难以维护。
//【示例】
// 生活中的通过中介者交互的场景有很多,比如聊天室和房屋中介等。
class Mediator;
// 抽象人
class Person
{
public:
Person(const std::string &name) : m_name(name){ }
virtual ~Person(){ }
public:
virtual void SendMessage(Mediator * mediator, std::string message) = 0;
virtual void GetMessage(Mediator * mediator, std::string& message) = 0;
std::string GetName();
private:
std::string m_name;
};
// 租房者
class Renter: public Person
{
public:
Renter(const std::string &name) : Person(name){ }
public:
void SendMessage(Mediator * mediator, std::string message);
void GetMessage(Mediator * mediator, std::string& message);
};
// 房东
class Landlord: public Person
{
public:
Landlord(const std::string &name) : Person(name){ }
public:
void SendMessage(Mediator * mediator, std::string message);
void GetMessage(Mediator * mediator, std::string& message);
};
// 抽象中介机构
class Mediator
{
public:
Mediator(const std::string &name) : m_name(name){ }
virtual ~Mediator(){ }
public:
virtual void Send(std::string message, Person * person) = 0;
void Add(Person *person);
std::string GetName();
private:
std::string m_name;
protected:
std::list<Person*> m_memberlist;
};
// 房屋中介
class HouseMediator : public Mediator
{
public:
HouseMediator(const std::string &name) : Mediator(name){ }
public:
void Send(std::string message, Person *person);
};
int TestMediator();
#endif
#include "Mediator.h"
std::string Person::GetName()
{
return m_name;
}
void Mediator::Add(Person *person)
{
m_memberlist.push_back(person);
}
std::string Mediator::GetName()
{
return m_name;
}
void Renter::SendMessage(Mediator * mediator, std::string message)
{
mediator->Send(message, this);
}
void Renter::GetMessage(Mediator * mediator, std::string& message)
{
printf("%s get a message from %s : %s \n", this->GetName().c_str(), mediator->GetName().c_str(), message.c_str());
}
void Landlord::SendMessage(Mediator * mediator, std::string message)
{
mediator->Send(message, this);
}
void Landlord::GetMessage(Mediator * mediator, std::string& message)
{
printf("%s get a message from %s : %s \n", this->GetName().c_str(), mediator->GetName().c_str(), message.c_str());
}
void HouseMediator::Send(std::string message, Person *person)
{
printf("%s send a message: %s \n", this->GetName().c_str(), message.c_str());
//房屋中介通知其他人接收消息
std::list<Person*>::iterator iter = m_memberlist.begin();
for ( ; iter != m_memberlist.end(); iter++)
{
Person * p = *iter;
if (p != person)
{
p->GetMessage(this, message);
}
}
}
int TestMediator()
{
Person * tom = new Landlord("tom");
Person * bob = new Renter("bob");
Person * alice = new Renter("alice");
Mediator * mediator = new HouseMediator("john");
mediator->Add(tom);
mediator->Add(bob);
mediator->Add(alice);
//tom 通过中介者发送消息
tom->SendMessage(mediator, "tom have a house to rent.");
delete tom;
delete bob;
delete alice;
delete mediator;
return 0;
}