c++ 行为型模式-中介者(Mediator)
1) 意图
用一个中介对象来封装一系列的对象交互,中介者使各个对象不需要显示地相互应用,从而使其耦合松散,并且可以独立地改变它们之间的交互
2) 结构
其中:
- Mediator定义一个接口用于各同事对象的通信
- ConcreteMediator 通过协调各个Colleague 类对象实现协助行为
- Colleague 知道它的中介者对象,每个Colleague 类对象在需要与其他Colleague 通信的时候与它的中介者通信
3) 适用性
- 一组对象通信方式复杂,产生的相互依赖关系结构混乱且难以理解
- 一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象
- 想定制一个分布在多个类中的行为,而又不想生成太多的子类
4) 举例
1 #include <iostream> 2 //ConcreteColleague1和ConcreteColleague2互相发消息,让对方通知出去,为减小其耦合,通过中介者Mediator实现这一功能 3 class Mediator; 4 class Colleague 5 { 6 public: 7 Colleague(Mediator* pMediator):m_pMediator(pMediator){} 8 virtual ~Colleague() {} 9 virtual void send(std::string msg) = 0; 10 protected: 11 Mediator* m_pMediator; 12 }; 13 class ConcreteColleague1:public Colleague 14 { 15 public: 16 ConcreteColleague1(Mediator* pMediator) :Colleague(pMediator) {} 17 virtual ~ConcreteColleague1() {} 18 virtual void send(std::string msg); 19 void notify(std::string msg) 20 { 21 std::cout <<" ConcreteColleague1 notify "<< msg.c_str() << std::endl; 22 } 23 }; 24 class ConcreteColleague2 :public Colleague 25 { 26 public: 27 ConcreteColleague2(Mediator* pMediator) :Colleague(pMediator) {} 28 virtual ~ConcreteColleague2() {} 29 virtual void send(std::string msg); 30 void notify(std::string msg) 31 { 32 std::cout <<" ConcreteColleague2 notify "<< msg.c_str() << std::endl; 33 } 34 }; 35 class Mediator 36 { 37 public: 38 Mediator() {} 39 virtual ~Mediator() {} 40 virtual void send(std::string msg, Colleague* pColleague) = 0; 41 virtual void setColleague1(Colleague* pColleague) = 0; 42 virtual void setColleague2(Colleague* pColleague) = 0; 43 44 }; 45 46 class ConcreteMediator:public Mediator 47 { 48 public: 49 ConcreteMediator() {}; 50 virtual ~ConcreteMediator() {} 51 void send(std::string msg, Colleague* pColleague) 52 { 53 ConcreteColleague1* pConcreteColleague1 = 54 dynamic_cast<ConcreteColleague1*>(pColleague); 55 if (pConcreteColleague1) 56 { 57 std::cout << "msg from ConcreteColleague1" << std::endl; 58 m_pColleague2->notify(msg); 59 } 60 else 61 { 62 std::cout << "msg from ConcreteColleague2" << std::endl; 63 m_pColleague1->notify(msg); 64 } 65 } 66 virtual void setColleague1(Colleague* pColleague) 67 { 68 m_pColleague1 = dynamic_cast<ConcreteColleague1*>(pColleague); 69 } 70 virtual void setColleague2(Colleague* pColleague) 71 { 72 m_pColleague2 = dynamic_cast<ConcreteColleague2*>(pColleague); 73 } 74 private: 75 ConcreteColleague1* m_pColleague1; 76 ConcreteColleague2* m_pColleague2; 77 }; 78 79 void ConcreteColleague1::send(std::string msg) 80 { 81 m_pMediator->send(msg,this); 82 } 83 void ConcreteColleague2::send(std::string msg) 84 { 85 m_pMediator->send(msg, this); 86 } 87 int main() 88 { 89 Mediator* pMediator = new ConcreteMediator(); 90 Colleague* pColleague1 = new ConcreteColleague1(pMediator); 91 Colleague* pColleague2 = new ConcreteColleague2(pMediator); 92 pMediator->setColleague1(pColleague1); 93 pMediator->setColleague2(pColleague2); 94 95 pColleague1->send("hello"); 96 pColleague2->send("world"); 97 system("pause"); 98 }