起因:尽管将一个系统分割成许多对象通常可以增加其可复用性,但对象间相互连接的激增又会降低其可复用性了。
大量的连接使得一个对象不可能在没有其他对象的支持下工作,系统表现为一个不可分割的整体。所以,对系统的行为进行大改动就困难了。
中介者模式:
用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
Colleague:叫做抽象同事类
ConcreteColleague:具体同事类,每个具体同事只知道自己的行为,而不了解其他同事类的情况,但它们却都认识中介者对象
Mediator:是抽象中介者,定义了同事对象到中介者对象的接口
ConcreteMediator:具体中介者对象,实现抽象类的方法。它需要知道所有具体同事类,并从具体同事接收消息,向具体同事对象发出命令。
中介者模式注意:
当系统出现了”多对多”交互复杂的对象群时,不要急于使用中介者模式,反思设计是否合理。
优点:
1中介者Mediator的出现减少了各个Colleague的耦合,使得可以独立地改变和复用各个Colleague类和Mediator。
2由于把对象如何协作进行了抽象,将中介作为一个独立的概念并封装在一个对象中,这样关注的对象就从对象各自本身的行为转移到它们之间的交互上来,也就是站在更宏观的角度去看待系统。
缺点:
由于具体中介者ConcreteMediator控制了集中化,于是就把交互复杂性变为了中介者的复杂性。使得中介者会变得比任何一个ConcreteConlleague都复杂。
适用:
中介者模式一般应用于一组对象以定义良好但是复杂的方式进行通信的场合。以及定制一个分部在多个类中的行为,而又不想生成太多的子类的场合。
main.cpp
#include <iostream>
#include <stdlib.h>
#include <memory>
#include "Country.h"
#include "UnitedNations.h"
using namespace std;
void process()
{
std::shared_ptr<UnitedNationsSecurityCouncil> ptrUNSC(new UnitedNationsSecurityCouncil());
USA usa(ptrUNSC,"USA");
Iraq iraq(ptrUNSC,"Iraq");
ptrUNSC->setIraq(iraq);
ptrUNSC->setUSA(usa);
usa.declare("不准研制核武器,否则明天攻陷伊拉克");
iraq.declare("狗娘样的美国佬,来啊!");
}
int main(int argc,char* argv[])
{
process();
system("pause");
return 0;
}
Country.h
#ifndef COUNTRY_H
#define COUNTRY_H
#include <memory>
#include <string>
class UnitedNations;
//国家
class Country
{
public:
Country(std::shared_ptr<UnitedNations> ptrMediator,const std::string& sName);
Country();
virtual ~Country(void);
protected:
std::shared_ptr<UnitedNations> _ptrMediator;//中介者
public:
std::string _sName;
};
//美国
class USA : public Country
{
public:
USA(std::shared_ptr<UnitedNations> ptrMediator,const std::string& sName);
~USA();
USA();
USA& operator=(const USA& usa);
void declare(const std::string& sMessage);
void getMessage(const std::string& sMessage);
};
//伊拉克
class Iraq : public Country
{
public:
Iraq(std::shared_ptr<UnitedNations> ptrMediator,const std::string& sName);
Iraq();
~Iraq();
Iraq& operator=(const Iraq& iraq);
void declare(const std::string& sMessage);
void getMessage(const std::string& sMessage);
};
#endif
Country.cpp
#include "Country.h"
#include <iostream>
#include "UnitedNations.h"
using namespace std;
Country::Country(std::shared_ptr<UnitedNations> ptrMediator,const std::string& sName):_ptrMediator(ptrMediator),_sName(sName)
{
}
Country::Country()
{
}
Country::~Country(void)
{
}
USA::USA(std::shared_ptr<UnitedNations> ptrMediator,const std::string& sName):Country(ptrMediator,sName)
{
}
USA::USA()
{
}
USA::~USA()
{
}
USA& USA::operator=(const USA& usa)
{
if(&usa != this)
{
this->_sName = usa._sName;
}
return *this;
}
//声明
void USA::declare(const std::string& sMessage)
{
_ptrMediator->declare(sMessage,*this);
}
void USA::getMessage(const std::string& sMessage)
{
cout << "美国获得对方信息:" << sMessage << endl;
}
Iraq::Iraq(std::shared_ptr<UnitedNations> ptrMediator,const std::string& sName):Country(ptrMediator,sName)
{
}
Iraq::Iraq()
{
}
Iraq::~Iraq()
{
}
Iraq& Iraq::operator=(const Iraq& iraq)
{
if(&iraq != this)
{
this->_sName = iraq._sName;
}
return *this;
}
//声明
void Iraq::declare(const std::string& sMessage)
{
_ptrMediator->declare(sMessage,*this);
}
void Iraq::getMessage(const std::string& sMessage)
{
cout << "伊拉克获得对方信息:" << sMessage << endl;
}
UnitedNations.h
#ifndef UNITEDNATIONS_H
#define UNITEDNATIONS_H
#include <string>
#include <memory>
#include "Country.h"
//联合国
class UnitedNations
{
public:
UnitedNations(void);
virtual ~UnitedNations(void);
virtual void declare(const std::string& sMessage,const Country& country);
};
//联合国安全理事会
class UnitedNationsSecurityCouncil : public UnitedNations
{
public:
//void setColleague1(std::shared_ptr<USA> ptrUSA);
//void setColleague2(std::shared_ptr<Iraq> ptrIraq);
UnitedNationsSecurityCouncil();
~UnitedNationsSecurityCouncil();
void setUSA(const USA& usa);
void setIraq(const Iraq& iraq);
void declare(const std::string& sMessage,const Country& country);
private:
//需要认识的国家
//std::shared_ptr<USA> _ptrUSA;
//std::shared_ptr<Iraq> _ptrIraq;
USA _usa;
Iraq _iraq;
};
#endif
UnitedNations.cpp
#include "UnitedNations.h"
UnitedNations::UnitedNations(void)
{
}
UnitedNations::~UnitedNations(void)
{
}
void UnitedNations::declare(const std::string& sMessage,const Country& country)
{
}
UnitedNationsSecurityCouncil::UnitedNationsSecurityCouncil():UnitedNations()
{
}
UnitedNationsSecurityCouncil::~UnitedNationsSecurityCouncil()
{
}
void UnitedNationsSecurityCouncil::setUSA(const USA& usa)
{
_usa = usa;
}
void UnitedNationsSecurityCouncil::setIraq(const Iraq& iraq)
{
_iraq = iraq;
}
void UnitedNationsSecurityCouncil::declare(const std::string& sMessage,const Country& country)
{
if(country._sName == _usa._sName)
{
_iraq.getMessage(sMessage);
}
else
{
_usa.getMessage(sMessage);
}
}