设计模式之中介者模式

中介者模式

  中介者模式又名调停者模式。将一个系统分割成许多对象一般能够增长其可复用性,可是对象间相互链接的激增又会下降其可复用性。由于大量的链接使得一个对象不可能在没有其它对象的支持下工做,系统表现为一个不可分割的总体,因此,对系统的行为进行任何较大的改动就十分困难了。解决这个问题的办法是两个类之间不直接进行通讯,若是一个类须要调用另外一个类的方法的话,能够经过第三者转发这个调用。经过中介者模式,能够将系统中的网状结构变成以中介者为中心的星状结构,每一个具体的对象再也不经过直接的联系与另外一个对象发生相互做用,而是经过中介者对象与两一个对象发生相互做用。中介者对象的设计,使得系统的结构不会由于新对象的引入形成大量的修改工做。ios

  中介者(Mediator)模式,用一个中介对象来封装一系列的对象交互。中介者使得各对象不须要显式的互相引用,从而使得其耦合松散,并且能够独立的改变他们之间的交互。数组

中介者模式的UML类图

Colleague叫作抽象同事类,而ConcreteColleague是具体同事类,每一个具体同事只知道本身的行为,而不了解其余同事类的状况,但它们都认识中介者对象,Mediator是抽象中介者,定义了同事对象到中介者对象的接口,ConcreteMediator是具体中介者对象,实现抽象类的方法,它须要知道全部具体同事类,并从具体同事类接收消息,向具体同事对象发出命令。Mediator是否存在,取决于系统以后是否有扩展的可能,同事类发送消息,通常都是经过中介者对象来发送的,这意味着具体的同事类须要持有一个中介者对象。ide

中介者模式的优缺点

优势:函数

  1.Meditor的出现减小了各个Colleague的耦合,使得能够独立的改变和复用各个Colleague类和Mediator。this

  2.因为把对象如何协做进行了抽象,将中介做为一个独立的概念并将其封装在一个对象中,这样关注的对象就从对象各自自己的行为转移到他们之间的交互上来,也就是站在一个更加宏观的角度来看待系统。spa

缺点:设计

  1.因为ConcreteMediator控制集中化,因而把就把交互复杂性变成了中介者的复杂性,这就使得中介者会变的比任何一个Concrete都复杂。code

使用场景:对象

  1.中介者模式通常应用于一组对象以定义良好可是复杂的方式进行通讯的场合,以及想定制一个分布在多个类中的行为,而又不想生成太多的子类的场合。blog

代码示例

  问题模型:一个货运体系,有负责集中发布货运信息的中介公司(对应于中介者模式中的Mediator),有货主,当货主有货物须要运送时,要求本身注册过的中介公司发布这条货运信息,中介公司再负责把这条中介信息广播给全部向本公司注册过的火车司机。这里火车司机和货主就至关因而具体的同事类。

1.抽象同事类(UML类图中的Colleague类)

#ifndef COLLEAGUE_H_
#define COLLEAGUE_H_

//这个类即能表明货主也能表明货车司机,因此它须要同时具有接收消息和发送消息的能力
//在中介模式中消息的发送和接收都是经过中介者来完成的,具体同事类,发布消息时要委托中介者发布,而接收消息虽然是从中介者来接收,但其实是从其它具体同事类那里接收信息的,
//你能够把中介者当成一个布告牌
#include <string>
class Mediator;

class Colleague
{
protected:
   std::string m_strName;
   Mediator *m_Mediator{nullptr};    //使具体同事类认识中介者,在具体的同事类中,须要经过构造函数为它赋值
public:
   virtual void sendMessage(const std::string strMessgae) const = 0;  //委托本身认识的中介者(m_Mediator)把这个消息发布出去
   virtual void receiveMessage(const Colleague *objColleague,const std::string strMessage) const = 0; //经过中介者,接收来自于信息发布者的消息
   virtual std::string getName() const = 0;
   Colleague() = default;
   virtual ~Colleague() = default;
};
#endif
Colleague

2.抽象中介者类(UML类图中的Mediator类)

抽象中介者须要知道一个同事列表,因此必然须要维护一个同事类的数组,以及同事类向中介者注册、注销本身的方法。此外,任何同事类的消息都将经过中介者转发,因此,中介者类还须要有一个Send方法负责转发消息。

#ifndef MEDIATOR_H_
#define MEDIATOR_H_

#include <list>
#include <string>
class Colleague;

class Mediator
{
protected:
    std::list<Colleague *> m_listColleague;
public:
    //货车司机向中介公司注册本身
    void registerColleague(Colleague * objColleague)
    {
    m_listColleague.push_back(objColleague);
    }
    //货车司机从中介公司注销本身的帐号
    void removeColleague(Colleague *objColleague)
    {
    m_listColleague.remove(objColleague);
    }
    //中介公司接收货主的消息,并把这条消息转发给全部注册了的货车司机
   virtual void distributeMessage(const Colleague *objColleagus,const std::string strMessage) const = 0;
   Mediator() = default;
   virtual ~Mediator() = default;
};
#endif
Mediator

3.具体同事类(UML类图中的ConcreteColleague类)

#ifndef CONCRETECOLLEAGUE_H_
#define CONCRETECOLLEAGUE_H_
//具体的同事类,在内部,具体的消息发送过程由中介者完成

#include "Colleague.h"
#include <iostream>
class Mediator;
class ConcreteColleague : public Colleague
{
public:
    std::string getName() const override
    {
    return m_strName;
    }
    void sendMessage(const std::string strMessage) const override;
    void receiveMessage(const Colleague* objColleague,const std::string strMessage) const override;
    ConcreteColleague(Mediator * objMediator,const std::string strName)
    {
    m_Mediator = objMediator;
    m_strName = strName;
    }
    ~ConcreteColleague() = default;
};
#endif

#include "ConcreteColleague.h"
#include "Mediator.h"

//委托中介者将消息发布出去
void ConcreteColleague::sendMessage(const std::string strMessage) const
{  
    if(nullptr != m_Mediator)
    {
     m_Mediator->distributeMessage(this,strMessage);
    }
}

//接收从中介那里分发的来自于其它同事类的消息
void ConcreteColleague::receiveMessage(const Colleague* objColleague,const std::string strMessage) const
{
    if(nullptr != m_Mediator)
    {
    std::cout << "Sender's Name is :"<< objColleague->getName() << "Message:" << strMessage << ".Receiver's name is :" << getName() << std::endl;
    }
}
ConcreteColleague

4.具体中介者类(UML类图中的ConcreteMediator类)

#ifndef CONCRETEMEDIATOR_H_
#define CONCRETEMEDIATOR_H_

#include "Mediator.h"
//具体的中介者,在本例中,这个中介者的具体做用就是把来自于具体同事对象的消息,转发给出发布消息者以外,系统内的其它同事对象
class ConcreteMediator:public Mediator
{
public:
    void distributeMessage(const Colleague* objColleague,const std::string strMessage) const override;
    ConcreteMediator() = default;
    ~ConcreteMediator() = default;
};
#endif

#include "ConcreteMediator.h"
#include "Colleague.h"

void ConcreteMediator::distributeMessage(const Colleague* objColleague,const std::string strMessage) const
{
    for(auto value : m_listColleague)
    {
    //使用条件判断,防止中介者将信息发布者回传给了本身
    if(objColleague != value)
    {
        value->receiveMessage(objColleague,strMessage);
    }
    }
}
ConcreteMediator

5.Client

#include "ConcreteMediator.h"
#include "ConcreteColleague.h"

using namespace std;
int main(int argc,char *argv[])
{
    //中介公司
    ConcreteMediator objConcreteMediator;
    //货主,让货主认识中介公司
    ConcreteColleague objConcreteColleague(&objConcreteMediator,"SenderA");
    //货主向中介公司注册本身的帐户
    objConcreteMediator.registerColleague(&objConcreteColleague);
    //货车司机A,使得货车司机认识中介公司
    ConcreteColleague objReceiverA(&objConcreteMediator,"ReceiverA");
    //货车司机A向中介公司注册本身的帐户
    objConcreteMediator.registerColleague(&objReceiverA);
    
    //货车司机B,使得货车司机B认识中介公司
    ConcreteColleague objReceiverB(&objConcreteMediator,"ReceiverB");
    //货车司机B向中介公司注册本身的帐户
    objConcreteMediator.registerColleague(&objReceiverB);
    
    //货主委托中介公司将信息发布出去
    objConcreteColleague.sendMessage("you ren ke yi bang wo ba zhe xie yu mi yun song dao qi tai xian ma?yun fei 1000/dun.");
    return (1);
}
Client
相关文章
相关标签/搜索