设计模式(19)中介者模式

中介者模式

如果在一个系统中,各个对象之间存在多对多的相互关系,可以将对象之间的一些交互行为从各个对象中分离出来,集中封装在一个中介者对象中,使其耦合松散,并由中介者统一协调。

通过中介者,对象之间的多对多关系就简化为了更简单的一对多的关系。

中介者模式:定义一个对象来封装一系列对象的交互。中介者模式使各个对象之间不需要显示地相互引用,从而使其耦合松散,而且用户可以独立地改变它们之间的交互。

中介者模式简介

在这里插入图片描述
由图可知,中介者模式主要有以下角色:

  • Mediator(抽象中介者):声明一个用于与各个同事对象之间交互的接口,通常声明一个注册方法,用于增加同事对象;
  • ConcreteMediator(具体中介者):实现上面的接口,协调各个同事对象来实现协作行为,维持对各个同事对象的引用;
  • Colleague(抽象同事类):声明各个同事类公有的接口,同时维持了一个对抽象中介者类的引用;
  • ConcreteColleague(具体同事类): 具体实现接口,具体同事类只需与中介者通信,通过中介者完成与其他同事类的通信。

中介者代码实例

#include <iostream>

using namespace std;

class Mediator;

class Colleague
{
    
    
public:
  Colleague(Mediator *pMediator) : m_pMediator(pMediator) {
    
    }

  virtual void Send(wchar_t *message) = 0;

protected:
  Mediator *m_pMediator;
};

class ConcreteColleague1 : public Colleague
{
    
    
public:
  ConcreteColleague1(Mediator *pMediator) : Colleague(pMediator) {
    
    }

  void Send(wchar_t *message);

  void Notify(wchar_t *message)
  {
    
    
    wcout << message << endl;
  }
};

class ConcreteColleague2 : public Colleague
{
    
    
public:
  ConcreteColleague2(Mediator *pMediator) : Colleague(pMediator) {
    
    }

  void Send(wchar_t *message);

  void Notify(wchar_t *message)
  {
    
    
    cout << "ConcreteColleague2 is handling the message." << endl;
    wcout << message << endl;
  }
};

class Mediator
{
    
    
public:
  virtual void Sent(wchar_t *message, Colleague *pColleague) = 0;
};

class ConcreteMediator : public Mediator
{
    
    
public:
  // The mediator forward the message
  void Sent(wchar_t *message, Colleague *pColleague)
  {
    
    
    ConcreteColleague1 *pConcreteColleague1 = dynamic_cast<ConcreteColleague1 *>(pColleague);
    if (pConcreteColleague1)
    {
    
    
      cout << "The message is from ConcreteColleague1. Now mediator forward it to ConcreteColleague2" << endl;
      if (m_pColleague2)
      {
    
    
        m_pColleague2->Notify(message);
      }
    }
    else
    {
    
    
      if (m_pColleague1)
      {
    
    
        m_pColleague1->Notify(message);
      }
    }
  }

  void SetColleague1(Colleague *pColleague)
  {
    
    
    m_pColleague1 = dynamic_cast<ConcreteColleague1 *>(pColleague);
  }

  void SetColleague2(Colleague *pColleague)
  {
    
    
    m_pColleague2 = dynamic_cast<ConcreteColleague2 *>(pColleague);
  }

private:
  // The Mediator knows all the Colleague
  ConcreteColleague1 *m_pColleague1;
  ConcreteColleague2 *m_pColleague2;
};

void ConcreteColleague1::Send(wchar_t *message)
{
    
    
  // The second parameter mark where the message comes from
  m_pMediator->Sent(message, this);
}

void ConcreteColleague2::Send(wchar_t *message)
{
    
    
  m_pMediator->Sent(message, this);
}

int main()
{
    
    
  // Create the mediator
  Mediator *pMediator = new ConcreteMediator();

  Colleague *pColleague1 = new ConcreteColleague1(pMediator);
  Colleague *pColleague2 = new ConcreteColleague2(pMediator);

  ConcreteMediator *pConcreteMediator = dynamic_cast<ConcreteMediator *>(pMediator);
  pConcreteMediator->SetColleague1(pColleague1);
  pConcreteMediator->SetColleague2(pColleague2);

  wchar_t message[260] = L"Where are you from?";
  // pColleague1->Send(message);
  pColleague2->Send(message);

  return 0;
}

中介者模式总结

优缺点

  • 减少了子类生成,Mediator将原本分布于多个对象间的行为集中在一起。改变这些行为只需生成Meditator的子类即可。这样各个Colleague类可被重用;
  • 它将各Colleague解耦,Mediator有利于各Colleague间的松耦合。你可以独立的改变和复用各Colleague类和Mediator类;
  • 它简化了对象协议,用Mediator和Colleague间的一对多的交互来代替多对多的交互。一对多的关系更容易理解、维护和扩展;
  • 它对对象如何协作进行了抽象,将中介作为一个独立的概念并将其封装在一个对象中,使你将注意力从对象各自本身的行为转移到它们之间的交互上来。这有助于弄清楚一个系统中的对象是如何交互的;
  • 它使控制集中化,中介者模式将交互的复杂性变为中介者的复杂性。因为中介者封装了协议,它可能变得比任一个Colleague都复杂。这可能使得中介者自身成为一个难于维护的庞然大物。

使用场合

在下列情况下使用中介者模式:

  • 一组对象以定义良好但是复杂的方式进行通信。产生的相互依赖关系结构混乱且难以理解;
  • 一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象;
  • 想定制一个分布在多个类中的行为,而又不想生成太多的子类。

Guess you like

Origin blog.csdn.net/qq_24649627/article/details/115486064