中介者模式(MediatorPattern)用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。中介者是对象的通信中心。当一个对象需要与另一个对象通信时,它不会直接调用另一个对象。相反,它会调用中介者对象,其主要职责是将消息路由到目标对象。它允许开发人员不必管理对象之间的链接。
中介者模式简化了对象之间的交互,它用中介者和同事的一对多交互代替了原来同事之间的多对多交互,一对多关系更容易理解、维护和扩展,将原本难以理解的网状结构转换成相对简单的星型结构。中介者模式可将各同事对象解耦。中介者有利于各同事之间的松耦合,可以独立地改变和复用每一个同事和中介者,增加新的中介者和新的同事类都比较方便,更好地符合“开闭原则”。可以减少子类生成,中介者将原本分布于多个对象间的行为集中在一起,改变这些行为只需生成新的中介者子类即可,这使各个同事类可被重用,无须对同事类进行扩展。
如果存在大量同事之间的交互,中介者将会变得非常复杂,使得系统难以维护。适用场景系统中对象之间存在比较复杂的引用关系,导致它们之间的依赖关系结构混乱而且难以复用该对象。想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。
中介-客户与房东之间的桥梁
Mediator
说起中介,很多人第一印象是房产中介,专门负责新房、二手房买卖、以及租房等业务。
奔波在一线城市的人,想必都经历过找房的辛酸(北漂的我默默地路过),不通过中介,想找到一个合适的小窝?不存在的。。。社区驻守、客户介绍、网络拓客、花钱买房源信息,对于中介来说,这些简直都是轻车熟路,房源哪里逃!更可怕的是,前一秒是独家,下一秒就是千百家。
这里,中介是对象的通信中心。当房东需要与租客通信时,他们之间不会直接交互,而是通过中介将消息发送给目标对象。
由于中介需要和所有参与者打交道,所以它除了注册参与者之外,还需要将发送者的消息传递出去:
//mediator.h#pragmaonce#include"colleague.h"#includeclassIColleague;//抽象中介者classIMediator{public://注册参与者virtualvoidregisterColleague(IColleague*colleague){m_colleagues.emplace_back(colleague);}conststd::list
//concrete_mediator.h#ifndefCONCRETE_MEDIATOR_H#defineCONCRETE_MEDIATOR_H#include"mediator.h"//具体中介者classConcreteMediator:publicIMediator{public://将发送者的消息发送给所有参与者(但不包括发送者自己)virtualvoiddistributeMessage(constIColleague*sender,conststd::string&message)constoverride{for(constIColleague*c:getColleagues())if(c!=sender)//不要将消息发送给自己c->receiveMessage(sender,message);}};#endif//CONCRETE_MEDIATOR_H注意:这里需要添加限制c!=sender,防止将消息回传给发送者自己。
由于房东和租客均由同事类表示,所以既需要(房东)发送消息,又需要(租客)接收消息:
//colleague.h#pragmaonce#include"mediator.h"#include
//concrete_colleague.h#ifndefCONCRETE_COLLEAGUE_H#defineCONCRETE_COLLEAGUE_H#include"colleague.h"#include //main.cpp#include"concrete_colleague.h"#include"concrete_mediator.h"#ifndefSAFE_DELETE#defineSAFE_DELETE(p){if(p){delete(p);(p)=NULL;}}#endifintmain(){//房东IColleague*landlord=newConcreteColleague("Tom");//租客IColleague*jerry=newConcreteColleague("Jerry");IColleague*tuffy=newConcreteColleague("Tuffy");//中介者-添加租客ConcreteMediatormediator;mediator.registerColleague(jerry);mediator.registerColleague(tuffy);//房东通过中介将消息发送出去landlord->sendMessage(mediator,"Xi'erqi,twobedroomhouse,6000/month.");SAFE_DELETE(jerry);SAFE_DELETE(tuffy);getchar();return0;}输出如下: JerryreceivedthemessagefromTom:Xi’erqi,twobedroomhouse,6000/month.TuffyreceivedthemessagefromTom:Xi’erqi,twobedroomhouse,6000/month.