美文网首页设计模式 BY C++C++设计模式
C++ 设计模式 —— 17.中介者模式

C++ 设计模式 —— 17.中介者模式

作者: JeremyYv | 来源:发表于2019-12-29 10:15 被阅读0次
  • 中介者模式:一种行为型设计模式

  • 应用场景:
    一般来说,大型的软件在开发的过程中会使用模块化的开发方式。以我现在参与的项目举例,完整的软件包括交互、检索、算路、引导等等多个模块,这样有利于模块之间的独立开发,提高整体开发效率。
    但是无论模块之间如何独立,总是会有需要模块间通信的时候。
    例如用户通过界面交互,发起检索,这个过程需要交互与检索两模块间通信,将用户的意图由交互模块传递至检索模块。
    这就会产生一个扩展性上的问题。如果模块有很多,且每个模块都向外提供了唯一的接收消息的接口,那么一个模块如果需要与其他所有模块通信,则需要记录其他所有模块的通信接口,同理每个模块都要记录所有与自己相关联的模块的通信接口。首先这就是一件很冗余并降低开发效率的事情。
    其次,一旦有一天,某个模块修改了自己所提供的通信接口,或者增加了一个新模块,尤其是后者,在公司项目发展过程中是很正常的事情。那么所有模块关于其他模块通信接口的记录可能都需要修改或增加,这在拥有庞大模块数量的项目中,是很恐怖的事情。
    此时可以考虑中介者模式
  • 举例:
    假设现在有3个模块A B CMessageABA B间双向传递的一个消息,同理还有MessageAC、MessageBC
    引入一个中介者,它手中记录着各模块的通信接口通信协议,协议即是一种约定A B两模块间约定通过MessageAB来传递某种信息,即是这两模块间的一个协议。模块间通信都将消息发给中介者,中介者无需关注消息具体用来传递什么信息,只需要关注协议双方,通过正确的通信接口转发消息,确保消息的转发对象正确即可,而消息的解析处理在接收模块内部进行。
    这样如果有通信接口修改或增加新模块,协议双方将新协议告知中介者记录即可
  • 实现方式:
    中介者对象中需要保存所有需转发消息的模块指针作为成员变量。
    各模块类中也需要保存负责转发消息的中介者指针作为成员变量。
    各模块类中需要实现发送与接收消息的方法。模块发送消息时调用中介者的转发接口,中介者确定接收目标后调用目标的接收接口
    下面代码中为了简化协议,我统一了各模块接收消息的接口名称。

以下是中介者模式的简单代码实现
#include <iostream>
using namespace std;

/*
 * 约定三种协议
 * MessageAB是AB模块间通信的消息
 * MessageAC是AC模块间通信的消息
 * MessageBC是BC模块间通信的消息
 */
enum Message
{
    MessageAB,
    MessageAC,
    MessageBC,
};

class ModuleBase;
//中介者基类,提供转发接口
class MediatorBase
{
public:
    virtual void Transmit(Message enMessage, ModuleBase* pFrom) = 0;
};

//模块基类,实现向外发消息的方法
class ModuleBase
{
public:
    ModuleBase(MediatorBase* pMediator):m_pMediator(pMediator){}
    //模块向外发消息的方法
    void SendMessage(Message enMessage)
    {
        m_pMediator->Transmit(enMessage, this);
    }

    //模块接收消息的接口,由模块自己实现
    virtual void vNotify(Message enMessage) = 0;

protected:
    //每个模块内都有一份负责分发消息的中介者
    MediatorBase* m_pMediator;
};

//模块A
class ModuleA : public ModuleBase
{
public:
    ModuleA(MediatorBase* pMediator):ModuleBase(pMediator){}
    virtual void vNotify(Message enMessage)
    {
        switch(enMessage)
        {
        case MessageAB:
            cout << "ModuleA get MessageAB from ModuleB" << endl;
            break;
        case MessageAC:
            cout << "ModuleA get MessageAC from MoudleC" << endl;
            break;
        default:
            break;
        }
    }
};

//模块B
class ModuleB : public ModuleBase
{
public:
    ModuleB(MediatorBase* pMediator):ModuleBase(pMediator){}
    virtual void vNotify(Message enMessage)
    {
        switch(enMessage)
        {
        case MessageAB:
            cout << "ModuleB get MessageAB from ModuleA" << endl;
            break;
        case MessageBC:
            cout << "ModuleB get MessageBC form ModuleC" << endl;
            break;
        default:
            break;
        }
    }
};

//模块C
class ModuleC : public ModuleBase
{
public:
    ModuleC(MediatorBase* pMediator):ModuleBase(pMediator){}
    virtual void vNotify(Message enMessage)
    {
        switch(enMessage)
        {
        case MessageAC:
            cout << "ModuleC get MessageAC from ModuleA" << endl;
            break;
        case MessageBC:
            cout << "ModuleC get MessageBC form ModuleB" << endl;
            break;
        default:
            break;
        }
    }
};

//中介者实现类
class ConcreteMediator : public MediatorBase
{
public:
    ConcreteMediator():m_pModA(NULL),m_pModB(NULL),m_pModC(NULL){}
    void Transmit(Message enMessage, ModuleBase* pFrom)
    {
        switch(enMessage)
        {
        case MessageAB:
            {
                ModuleA* pFromWhere = dynamic_cast<ModuleA*>(pFrom);
                //能通过dynamic_cast转换为不为NULL的指针,可确认指针指向的子类类型
                if(NULL != pFromWhere)
                {
                    m_pModB->vNotify(enMessage);
                }
                else
                {
                    m_pModA->vNotify(enMessage);
                }
            }
            break;
        case MessageAC:
            {
                ModuleA* pFromWhere = dynamic_cast<ModuleA*>(pFrom);
                if(NULL != pFromWhere)
                {
                    m_pModC->vNotify(enMessage);
                }
                else
                {
                    m_pModA->vNotify(enMessage);
                }
            }
        case MessageBC:
            {
                ModuleB* pFromWhere = dynamic_cast<ModuleB*>(pFrom);
                if(NULL != pFromWhere)
                {
                    m_pModC->vNotify(enMessage);
                }
                else
                {
                    m_pModB->vNotify(enMessage);
                }
            }
        }
    }

    void SetModuleA(ModuleBase* pModuleA){m_pModA = pModuleA;}
    void SetModuleB(ModuleBase* pModuleB){m_pModB = pModuleB;}
    void SetModuleC(ModuleBase* pModuleC){m_pModC = pModuleC;}

private:
    ModuleBase* m_pModA;
    ModuleBase* m_pModB;
    ModuleBase* m_pModC;
};
主函数中的使用
int main()
{
    MediatorBase* pMediator = new ConcreteMediator();

    //为所有模块指定中介者
    ModuleBase* pModA = new ModuleA(pMediator);
    ModuleBase* pModB = new ModuleB(pMediator);
    ModuleBase* pModC = new ModuleC(pMediator);

    //为中介者设定模块
    ConcreteMediator* pConcreteMediator = dynamic_cast<ConcreteMediator*>(pMediator);
    pConcreteMediator->SetModuleA(pModA);
    pConcreteMediator->SetModuleB(pModB);
    pConcreteMediator->SetModuleC(pModC);

    //各模块间开始互发消息
    pModA->SendMessage(MessageAC);
    pModB->SendMessage(MessageBC);
    pModC->SendMessage(MessageBC);

    return 0;
}
控制台输出结果
ModuleC get MessageAC from ModuleA
ModuleC get MessageBC form ModuleB
ModuleB get MessageBC form ModuleC

如有错误,欢迎指正

相关文章

网友评论

    本文标题:C++ 设计模式 —— 17.中介者模式

    本文链接:https://www.haomeiwen.com/subject/umqyoctx.html