Mediator中介者模式
作用:用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
UML如下:
Colleage抽象同事类,而ConcreteColleage是具体同时类,每个具体同事只知道自己的行为,而不了解其他同事类的情况,但它们却都认识中介者对象,Mediator是抽象中介者,定义了同事对象到中介者对象的接口,ConcreteMediator是具体中介者对象,实现抽象类的方法,它需要知道所有具体同事类,并从具体同事接受消息,向具体同事对象发出命令。
Colleage类,抽象同事类
Mediator,抽象中介者类
说明:
1. Mediator 模式中,每个Colleague 维护一个 Mediator,当要进行通信时,每个具体的 Colleague 直接向ConcreteMediator 发信息,至于信息发到哪里,则由 ConcreteMediator 来决定。
2. ConcreteColleagueA 和 ConcreteColleagueB 不必维护对各自的引用,甚至它们也不知道各个的存在。
3. 优点是,各个 Colleague 减少了耦合。
4. 缺点是,由于 Mediator 控制了集中化,于是就把 Colleague 之间的交互复杂性变为了中介者的复杂性,也就是中介者会变的比任何一个 Colleague 都复杂。
中介者模式很容易在系统中应用,也很容易在系统中误用。当系统中出现了“多对多”交互复杂的对象群时,不要急于使用中介者模式,而要先反思你的系统在设计上是不是合理。
Mediator的出现减少了各个Colleage的耦合,使得可以独立地改变和复用各个Colleage类和Mediator;
由于把对象如何协作进行了抽象,将中介作为一个独立的概念并将其封装在一个对象中,这样关注的对象就从对象各自本身的行为转移到它们之间的交互上来,也就是站在一个更宏观的角度去看待系统。
由于ConcreteMediator控制了集中化,于是就把交互复杂性变为了中介者的复杂性,这使得中介者会变得比任何一个ConcreteColleage都复杂。
中介者模式的优点来自集中控制,其缺点也是它。
中介者模式一般应用于一组对象以定义良好但是复杂的方式进行通信的场合。
代码如下:
Mediator.h
1 #ifndef _MEDIATOR_H_ 2 #define _MEDIATOR_H_ 3 4 #include <string> 5 6 using namespace std; 7 8 class Mediator; 9 10 class Colleage 11 { 12 public: 13 virtual ~Colleage(); 14 virtual void SetMediator(Mediator*); 15 virtual void SendMsg(string) = 0; 16 virtual void GetMsg(string) = 0; 17 protected: 18 Colleage(Mediator*); 19 Mediator* _mediator; 20 private: 21 22 }; 23 24 class ConcreteColleageA : public Colleage 25 { 26 public: 27 ~ConcreteColleageA(); 28 ConcreteColleageA(Mediator*); 29 virtual void SendMsg(string msg); 30 virtual void GetMsg(string); 31 protected: 32 private: 33 }; 34 35 class ConcreteColleageB : public Colleage 36 { 37 public: 38 ~ConcreteColleageB(); 39 ConcreteColleageB(Mediator*); 40 virtual void SendMsg(string msg); 41 virtual void GetMsg(string); 42 protected: 43 private: 44 }; 45 46 class Mediator 47 { 48 public: 49 virtual ~Mediator(); 50 virtual void SendMsg(string,Colleage*) = 0; 51 protected: 52 Mediator(); 53 private: 54 }; 55 56 class ConcreteMediator : public Mediator 57 { 58 public: 59 ConcreteMediator(); 60 ~ConcreteMediator(); 61 void SetColleageA(Colleage*); 62 void SetColleageB(Colleage*); 63 virtual void SendMsg(string msg,Colleage*); 64 protected: 65 private: 66 Colleage* m_ColleageA; 67 Colleage* m_ColleageB; 68 }; 69 #endif
Mediator.cpp
1 #include "Mediator.h" 2 #include <iostream> 3 #include <string> 4 5 using namespace std; 6 7 Colleage::Colleage(Mediator* pMediator) 8 { 9 this->_mediator = pMediator; 10 } 11 12 Colleage::~Colleage() 13 {} 14 15 void Colleage::SetMediator(Mediator* pMediator) 16 { 17 this->_mediator = pMediator; 18 } 19 20 ConcreteColleageA::ConcreteColleageA(Mediator* pMediator) : Colleage(pMediator) 21 { 22 } 23 24 ConcreteColleageA::~ConcreteColleageA() 25 { 26 } 27 28 void ConcreteColleageA::SendMsg(string msg) 29 { 30 this->_mediator->SendMsg(msg,this); 31 } 32 33 void ConcreteColleageA::GetMsg(string msg) 34 { 35 cout << "ConcreteColleageA Receive:"<< msg << endl; 36 } 37 38 ConcreteColleageB::ConcreteColleageB(Mediator* pMediator) : Colleage(pMediator) 39 { 40 } 41 42 ConcreteColleageB::~ConcreteColleageB() 43 { 44 } 45 46 void ConcreteColleageB::SendMsg(string msg) 47 { 48 this->_mediator->SendMsg(msg,this); 49 } 50 51 void ConcreteColleageB::GetMsg(string msg) 52 { 53 cout << "ConcreteColleageB Receive:" << msg << endl; 54 } 55 56 Mediator::Mediator() 57 {} 58 59 Mediator::~Mediator() 60 {} 61 62 ConcreteMediator::ConcreteMediator() 63 {} 64 65 ConcreteMediator::~ConcreteMediator() 66 {} 67 68 void ConcreteMediator::SetColleageA(Colleage* p) 69 { 70 this->m_ColleageA = p; 71 } 72 73 void ConcreteMediator::SetColleageB(Colleage* p) 74 { 75 this->m_ColleageB = p; 76 } 77 78 void ConcreteMediator::SendMsg(string msg,Colleage* p) 79 { 80 if(p == this->m_ColleageA) 81 { 82 this->m_ColleageB->GetMsg(msg); 83 } 84 else if(p == this->m_ColleageB) 85 { 86 this->m_ColleageA->GetMsg(msg); 87 } 88 }
main.cpp
1 #include "Mediator.h" 2 3 int main() 4 { 5 ConcreteMediator* pMediator = new ConcreteMediator(); 6 7 Colleage* p1 = new ConcreteColleageA(pMediator); 8 Colleage* p2 = new ConcreteColleageB(pMediator); 9 10 pMediator->SetColleageA(p1); 11 pMediator->SetColleageB(p2); 12 13 p1->SendMsg("xxx"); 14 p2->SendMsg("ooo"); 15 return 0; 16 }
结果如下: