中介者模式(Mediator):用一個中介物件來封裝一系列的物件互動。中介者使各物件不需要明確地互動引用,從而使耦合鬆散,而且可以獨立地改變它們之間的交互作用。
四個角色:
抽像中介者Mediator
具體中介者對象ConcreteMediator
抽象類Abstract
具體抽象類ConcreteAbstract
化的中介者模式,可以獨立地改變和重複使用各個Abstract類別和Mediator。
由於把對像如何協作進行了抽象,將中介作為一個獨立的概念並將其封裝在一個對像中,這樣關注的對象就從對象各自本身的行為轉移到它們之間的交互上來,也就是站在一個更客觀的角度去看待系統。
中介者模式缺點:
由於ConcreteMediator控制了集中化,於是就把交互複雜性變為中介者的複雜性,這就使得中介者會變得比任何一個ConcreteAbstract都負責。
模式實現:
[code]//前向声明 class Abstract; //中介者抽象类 class Mediator{ public: virtual void Send(std::string message, Abstract *abstract){} }; //抽象类 class Abstract{ protected: Mediator *mediator; public: //构造中介者 Abstract(Mediator *mediator){ this->mediator = mediator; } }; //具体抽象类1 class ConcreteAbstract1: public Abstract{ public: ConcreteAbstract1(Mediator *me):Abstract(me){} void Send(std::string message){ //中介者送出去 mediator->Send(message, this); } void Notify(std::string message){ std::cout << "ConcreteAbstract1 receive message: " << message << " ---(From ConcreteAbstract2)" << std::endl; } }; //具体抽象类2 class ConcreteAbstract2: public Abstract{ public: ConcreteAbstract2(Mediator *me):Abstract(me){} void Send(std::string message){ //中介者送出去 mediator->Send(message, this); } void Notify(std::string message){ std::cout << "ConcreteAbstract2 receive message: " << message << " ---(From ConcreteAbstract1)" << std::endl; } }; //具体中介者 class ConcreteMediator: public Mediator{ private: //需了解所存的具体抽象类对象 ConcreteAbstract1 *CA1; ConcreteAbstract2 *CA2; public: ConcreteMediator(){} void setConcreteMediator(ConcreteAbstract1 *CA1, ConcreteAbstract2 *CA2){ this->CA1 = CA1; this->CA2 = CA2; } virtual void Send(std::string message, Abstract *abstract){ if(abstract == CA1) CA2->Notify(message); else CA1->Notify(message); } };
[code]//Client int main(){ ConcreteMediator *m = new ConcreteMediator; //具体的抽象这认识具体的中介者 ConcreteAbstract1 *ca1 = new ConcreteAbstract1(m); ConcreteAbstract2 *ca2 = new ConcreteAbstract2(m); //让中介者认识两个具体的抽象类 m->setConcreteMediator(ca1, ca2); ca1->Send("Hello"); //Output: ConcreteAbstract2 receive message: Hello ---(From ConcreteAbstract1) ca2->Send("Hi"); //Output: ConcreteAbstract1 receive message: Hi ---(From ConcreteAbstract2) if(m != NULL){ delete m; m = NULL; } if(ca1 != NULL){ delete ca1; ca1 = NULL; } if(ca2 != NULL){ delete ca2; ca2 = NULL; } return 0; }