Mediator 中介者模式

来源:互联网 发布:幼儿园下载什么软件 编辑:程序博客网 时间:2024/04/28 21:52

     Mediator 中介者模式: 用一个中介对象封闭一系列的对象交互. 中介者使各对象不需要显式地相互引用,从而使其耦合松散, 而且可以独立地改变它们之间的交互. Mediator 模式提供将对象间的交互和通讯封装在一个类中,各个对象间的通信不必显式去声明和引用,大降低了系统和复杂性能. 中介者负责控制和协调一组对象间的交互,减少相互连接的数目.

     Mediator 中介者模式适用于:1.一组对象以定义良好但复杂的方式进行通信,产生的相互依赖关系结构混乱且难以理解. 2.一个对象引用其它很多对象并且直接与这些对象通信,导致难以复用该对象. 3.想定制一个分布在多个类中的行为,而又不想生成太多的子类.

Mediator 中介者模式的通用结构图如下:

mediator

参与者:

Mediator: 中介者,定义一个接口用于各同事(Colleague)对象通信.

ConcreteMediator: 具体的中介者, 通过协调各同事对象实现协作行为.了解并维护它的各个同事.

Colleague: 同事类,每一个同事类都知道它的中介者对象. 每一个同事对象在需要与其他的同事通信的时候,与它的中介者通信,中介者负责转达.中介者在各个同事间适当地转发请求以实现协作.

效果:

1.减少了子类的生成, Meditator 将原本分布于多个对象间的行为集中在一起,改变这些行为只需生成 Mediator 的子类即可,这样各个 Colleague 类可被重用.

2.它将各个 Colleague 解耦, Mediator有利于各 Colleague 间的松耦合,你可以独立的改变和利用各 Colleague 类和 Mediator 类.

3.它简化了对象协议,用 Mediator和各 Colleague 间的一对多交互来代替多对多的交互,一对多的关系更易于理解,维护和扩展.

4.它对对象如何协作进行了抽象,将中介者作为一个独立的概念并将其封装在一个对象中,使你将注意力从对象各自本身的行为转移到它们之间的交互上来.这有助于弄清楚一个系统中的对象是如何交互的.

5.它使控制集中化, 中介者模式将交互的复杂性变为中介者的性.因为中介者封装了协议,它可能变得比任一个 Colleague 都复杂.这可能使得中介者自身成为一个难于维护的诚然大物.

    实现时,当各 Colleague 仅与一个 Mediator 一起工作时,没有必要定义一个抽象的 Mediator 类. 实现 Mediator 与 Colleague 之间的通信时,可以使用 Observer 模式,将 Mediator 实现为一个 Observer,各个 Colleague 作为 Subject, 一旦其状态改变就发送通知给 Mediator. Mediator 作出的响应是将状态的结果传播给其他的 Colleague. 或者在 Mediator 中定义一个特殊的通知接口,各 Colleague 在通信时直接调用该接口.

Mediator 中介者模式代码示例:

   1:  //colleage.h
   2:  #pragma once
   3:   
   4:  #include <string> 
   5:   
   6:  class Mediator; 
   7:  class Colleage 
   8:  { 
   9:  public: 
  10:      virtual ~Colleage(); 
  11:      virtual void Aciton() = 0; 
  12:      virtual void SetState(const std::string& state) = 0; 
  13:      virtual std::string GetState() = 0; 
  14:  protected: 
  15:      Mediator* _mdt; 
  16:      std::string _state; 
  17:  protected: 
  18:      Colleage(); 
  19:      Colleage(Mediator* mdt); 
  20:  }; 
  21:  class ConcreteColleageA : public Colleage 
  22:  { 
  23:  public: 
  24:      ConcreteColleageA(); 
  25:      ConcreteColleageA(Mediator* mdt); 
  26:      ~ConcreteColleageA(); 
  27:      void Aciton(); 
  28:      void SetState(const std::string& state); 
  29:      std::string GetState(); 
  30:  //private: 
  31:      //std::string _sdt; 
  32:  }; 
  33:  class ConcreteColleageB : public Colleage 
  34:  { 
  35:  public: 
  36:      ConcreteColleageB(); 
  37:      ConcreteColleageB(Mediator* mdt); 
  38:      ~ConcreteColleageB(); 
  39:      void Aciton(); 
  40:      void SetState(const std::string& state); 
  41:      std::string GetState(); 
  42:  private: 
  43:      //std::string _name; 
  44:  }; 
.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }

 

   1:  //Mediator.h 
   2:  #pragma once
   3:   
   4:  class Colleage; 
   5:   
   6:  //中介者抽象基类
   7:  class Mediator 
   8:  { 
   9:  public: 
  10:      virtual ~Mediator(); 
  11:      virtual void DoActionFromAtoB() = 0; 
  12:      virtual void DoActionFromBtoA() = 0; 
  13:  protected: 
  14:      Mediator();  
  15:  }; 
  16:  //具体的中介者
  17:  class ConcreteMediator:public Mediator 
  18:  { 
  19:  public: 
  20:      ConcreteMediator(); 
  21:      ConcreteMediator(Colleage* clgA,Colleage* clgB); 
  22:      ~ConcreteMediator(); 
  23:   
  24:      //getMember and setMember
  25:      Colleage* GetConcreteColleageA(); 
  26:      Colleage* GetConcreteColleageB(); 
  27:      void  SetConcreteColleageA(Colleage* clgA); 
  28:      void  SetConcreteColleageB(Colleage* clgB); 
  29:   
  30:      void  IntroColleage(Colleage* clgA,Colleage* clgB); 
  31:   
  32:      void DoActionFromAtoB(); 
  33:      void DoActionFromBtoA(); 
  34:  private: 
  35:      Colleage* _clgA; 
  36:      Colleage* _clgB; 
  37:  }; 
.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }

 

   1:  //Colleage.cpp 
   2:  #include "Mediator.h" 
   3:  #include "Colleage.h" 
   4:  #include <iostream> 
   5:   
   6:  Colleage::Colleage() 
   7:  {   } 
   8:  Colleage::Colleage(Mediator* mdt) 
   9:  {   
  10:      this->_mdt = mdt; 
  11:  } 
  12:  Colleage::~Colleage() 
  13:  {    } 
  14:   
  15:  ///
  16:  ConcreteColleageA::ConcreteColleageA() 
  17:  {    } 
  18:  ConcreteColleageA::~ConcreteColleageA() 
  19:  {   } 
  20:  ConcreteColleageA::ConcreteColleageA(Mediator* mdt)
  21:      :Colleage(mdt)  
  22:  {   } 
  23:  std::string ConcreteColleageA::GetState() 
  24:  {   
  25:      return _state;  
  26:  } 
  27:  void ConcreteColleageA::SetState(const std::string& sdt) 
  28:  {   
  29:      _state = sdt; 
  30:  } 
  31:  void ConcreteColleageA::Aciton() 
  32:  { 
  33:      _mdt->DoActionFromAtoB(); 
  34:      std::cout << "State of ConcreteColleageA:" << " " 
  35:          << this->GetState() << std::endl; 
  36:  } 
  37:   
  38:  ///
  39:  ConcreteColleageB::ConcreteColleageB() 
  40:  {   } 
  41:  ConcreteColleageB::~ConcreteColleageB() 
  42:  {   } 
  43:  ConcreteColleageB::ConcreteColleageB(Mediator* mdt)
  44:      : Colleage(mdt) 
  45:  {    } 
  46:  void ConcreteColleageB::Aciton() 
  47:  {
  48:      _mdt->DoActionFromBtoA(); 
  49:      std::cout << "State of ConcreteColleageB:" << " "
  50:          << this->GetState() << std::endl; 
  51:  } 
  52:  std::string ConcreteColleageB::GetState() 
  53:  { 
  54:      return _state;
  55:  } 
  56:  void ConcreteColleageB::SetState(const std::string& sdt) 
  57:  {   
  58:      _state = sdt;  
  59:  } 
.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }

 

   1:   
   2:  //Mediator.cpp 
   3:  #include "Mediator.h" 
   4:  #include "Colleage.h" 
   5:   
   6:  Mediator::Mediator() {     } 
   7:  Mediator::~Mediator() {     } 
   8:  ConcreteMediator::ConcreteMediator() {     } 
   9:  ConcreteMediator::~ConcreteMediator() {     } 
  10:   
  11:  ConcreteMediator::ConcreteMediator(
  12:      Colleage* clgA,Colleage* clgB) 
  13:  {  
  14:      this->_clgA = clgA; 
  15:      this->_clgB = clgB; 
  16:  } 
  17:   
  18:  void ConcreteMediator::SetConcreteColleageA(
  19:       Colleage* clgA) 
  20:  {  
  21:      this->_clgA = clgA;   
  22:  } 
  23:  void ConcreteMediator::SetConcreteColleageB(
  24:       Colleage* clgB) 
  25:  {  
  26:      this->_clgB = clgB;  
  27:  } 
  28:  Colleage* ConcreteMediator::GetConcreteColleageA() 
  29:  { 
  30:      return _clgA;  
  31:  } 
  32:  Colleage* ConcreteMediator::GetConcreteColleageB() 
  33:  { 
  34:      return _clgB; 
  35:  } 
  36:  void ConcreteMediator::IntroColleage(
  37:         Colleage* clgA,Colleage* clgB) 
  38:  {  
  39:      this->_clgA = clgA; 
  40:      this->_clgB = clgB; 
  41:  } 
  42:  //对象间交互
  43:  void ConcreteMediator::DoActionFromBtoA() 
  44:  { 
  45:      _clgA->SetState(_clgB->GetState()); 
  46:  } 
  47:  void ConcreteMediator::DoActionFromAtoB() 
  48:  { 
  49:      _clgB->SetState(_clgA->GetState()); 
  50:  } 
.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }

 

   1:  //main.cpp 
   2:  #include "Mediator.h" 
   3:  #include "Colleage.h" 
   4:  #include <iostream> 
   5:   
   6:  int main(int argc,char* argv[]) 
   7:  { 
   8:      ConcreteMediator* m    = new ConcreteMediator(); 
   9:      ConcreteColleageA* c1  = new ConcreteColleageA(m); 
  10:      ConcreteColleageB* c2  = new ConcreteColleageB(m); 
  11:      m->IntroColleage(c1,c2); 
  12:   
  13:      //将 ConcreteColleageA 对象设置状态"old"
  14:      //ConcreteColleageB 也设置状态"old" ;
  15:      c1->SetState("old"); 
  16:      c2->SetState("old"); 
  17:      c1->Aciton(); 
  18:      c2->Aciton(); 
  19:      std::cout << std::endl; 
  20:   
  21:      //ConcreteColleageA 对象改变状态
  22:      //并在 Action 中和 ConcreteColleageB 对象进行通信
  23:      //并改变 ConcreteColleageB 对象的状态为 "new"
  24:      c1->SetState("new"); 
  25:      c1->Aciton(); 
  26:      c2->Aciton(); 
  27:      std::cout << std::endl; 
  28:   
  29:      //ConcreteColleageB 对象改变状态
  30:      //并在 Action 中和 ConcreteColleageA 对象进行通信
  31:      //并改变 ConcreteColleageA 对象的状态为 "old"
  32:      c2->SetState("old"); 
  33:      c2->Aciton(); 
  34:      c1->Aciton(); 
  35:   
  36:      return EXIT_SUCCESS; 
  37:  } 
.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }