Mediator Pattern --中介者模式原理及实现(C++)
主要参考《大话设计模式》和《设计模式:可复用面向对象软件的基础》两本书。本文介绍中介者模式的实现。
中介者模式:What it is:Define an object that encapsulates how a set of objects interact. Promotes loose coupling by keeping objects from referring to each other explicitly and it lets you vary their interactions independently.
用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。中介者模式的例子很多,大到联合国安理会,小到房屋中介,都扮演了中间者的角色,协调各方利益。
中介者模式很容易在系统中应用,也很容易在系统中误用。当系统出现了多对多交互复杂的对象群时,不要急于使用中介者模式,而要先反思你的系统在设计上是不是合理。
优点:Mediator的出现减少了各个Colleague的耦合,使得可以独立地改变和复用各个Colleague类和Mediator; 由于把对象如何协作进行了抽象,将中介作为一个独立的概念并将其封装在一个对象中,这样关注的对象就从对象各自本身的行为转移到它们之间的交互上来,也就是站在一个更宏观的角度去看待系统。
缺点:由于ConcreteMediator控制了集中化。于是就把交互的复杂性变为了中介者的复杂性,使得中介者比任何一个ConcreteColleague都复杂。
本文就以租房为例子,如果没有房屋中介,那么房客要自己找房东,而房东也要自己找房客,非常不方便。有了房屋中介机构就方便了,房东可以把要出租的房屋信息放到中介机构,而房客可以去中介机构咨询。在软件中,就是多个对象之间需要通信,如果没有中介,对象就需要知道其他对象,最坏情况下,可能需要知道所有其他对象,而有了中介对象就方便多了,对象只需与中介对象通信,而不用知道其他的对象。这就是中介者模式,下面以租房为例,给出中介者模式的UML图。
C++代码实现Mediator模式:
1 #include <iostream> 2 #include <string> 3 using namespace std; 4 5 #define SAFE_DELETE(p) if (p) { delete p; p = NULL; } 6 7 /*声明抽象中介类*/ 8 class Mediator; 9 10 /*定义抽象人类*/ 11 class Person 12 { 13 public: 14 virtual void SetMediator(Mediator *mediator){} 15 virtual void SendMessage(string &message){} 16 virtual void GetMessage(string &message){} 17 protected: 18 Mediator *p_mediator; //中介 19 }; 20 21 /*定义抽象中介类*/ 22 class Mediator 23 { 24 public: 25 virtual void Send(string &message, Person *person){} 26 virtual void SetRenter(Person *renter){} 27 virtual void SetLandlord(Person *landlord){} 28 29 }; 30 31 /*定义租客类*/ 32 class Renter:public Person 33 { 34 public: 35 void SetMediator(Mediator *mediator){p_mediator = mediator;} 36 void SendMessage(string &message){ p_mediator->Send(message,this);} 37 void GetMessage(string &message){cout<<"租房者收到房东发来的消息:"<<message;} 38 }; 39 40 /*定义房东类*/ 41 class Landlord:public Person 42 { 43 public: 44 void SetMediator(Mediator *mediator){p_mediator = mediator;} 45 void SendMessage(string &message){ p_mediator->Send(message,this);} 46 void GetMessage(string &message){cout<<"房东收到租客发来的消息:"<<message;} 47 }; 48 49 /*定义具体中介类*/ 50 class HouseMediator:public Mediator 51 { 52 public: 53 HouseMediator():p_renter(NULL),p_landlord(NULL){} 54 void SetRenter(Person *renter){p_renter = renter;} 55 void SetLandlord(Person *landlord){p_landlord = landlord;} 56 void Send(string &message, Person *person) 57 {//接收消息的对象为该对象的对应对象 58 if(person == p_renter) 59 p_landlord->GetMessage(message); 60 else 61 p_renter->GetMessage(message); 62 } 63 private: 64 Person *p_renter; 65 Person *p_landlord; 66 }; 67 int main(int argc, char *argv[]) 68 { 69 Mediator *mediator = new HouseMediator(); 70 Person *person1 = new Renter(); 71 Person *person2 = new Landlord(); 72 mediator->SetRenter(person1); 73 mediator->SetLandlord(person2); 74 person1->SetMediator(mediator); 75 person2->SetMediator(mediator); 76 person1->SendMessage(string("我想在深圳北站附近租套房子,一室一厅\n")); 77 person2->SendMessage(string("我出租一条房子,一室一厅,深圳北站附近\n")); 78 SAFE_DELETE(person1); 79 SAFE_DELETE(person2) 80 SAFE_DELETE(mediator); 81 return 0; 82 }