16.中介者模式

1.说明
请参见第一章节
2.中介者模式简介
中介者模式:用一个中介对象来封装一系列的对象交互,中介者使各个对象不需要显示地互相引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
注意:很容易在系统中应用,也很容易误用。当系统出现了“多对多”交互复杂的对象群时,不要急于使用中介这模式,而要反思这个模式是否合理。
中介这模式优缺点:mediator的出现减少了各个对象的耦合,使得可以独立地改变和复用各自的对象colleague和mediator。由于把对象如何协作进行了抽象,将中介作为一个独立的概念并将其封装在一个对象中,这样的关注的对象就从对象各自本身的行为转移到他们之间的交互上来。当中介者中汇聚了太多对象的时候,会导致中介者的复杂性,甚至时某一逻辑出错,导致整个的交互逻辑出错
中介者模式一般应用于一组对象良好,但是复杂的方式进行通信的场合。
注意:使用中介者模式时,这几个对象是平行对等的关系,不是依赖或是子类关系
这里写图片描述
摘自《大化设计模式》

3.UML
这里写图片描述

4.代码

//中介者基类
#ifndef __MEDIATOR_H
#define __MEDIATOR_H

#include <iostream>
#include <string>
#include <map>

class CBussiness;

//各个模块命令封装
typedef struct SRequest
{ 
    int cmd;                    // 0 广播  1单播
    int res;                    //返回 0 同意并处理 1不处理
    std::string sendmsg;        //命令发送信息 
    std::string backmsg;        //命令返回信息
    CBussiness* buss;           //发送的实例
} TRequest;

//所有对象的管理者
typedef std::map<std::string, CBussiness*> TBUSSMAP;

class CMediator
{
public:
    CMediator(){}
    virtual ~CMediator(){}
    //@return: 0 请求被接收 -1请求对象不存在
    virtual int delcare(std::string modulename, TRequest& req) = 0;

    void add_module(std::string name, CBussiness* buss)
    {
        m_modulemap.insert(std::make_pair(name, buss));
    }

protected:
    TBUSSMAP m_modulemap;
};

#endif

//具体实现类
#ifndef __BUSSNEDIATOR_H
#define __BUSSNEDIATOR_H

#include "Bussiness.h"
#include "Mediator.h"


class CBussMediator:public CMediator
{
public:
    virtual int delcare(std::string modulename, TRequest& req)
    {
        int nret = 0;
        //广播信息 是自己也要接收的
        if (0 == req.cmd)
        {
            for (TBUSSMAP::iterator it=m_modulemap.begin(); it!=m_modulemap.end(); it++)
            {
                it->second->notify(req);
            }
            std::cout<<"DEBUG:"<<"中介者完成"<<modulename.c_str()<<"广播请求"<<std::endl;
        }
        else
        {
            TBUSSMAP::iterator it=m_modulemap.find(modulename);
            if (m_modulemap.end() != it)
            {               
                it->second->notify(req);
                std::cout<<"DEBUG:"<<"中介者完成"<<modulename.c_str()<<"单播请求"<<std::endl;
            }   
            else
            {       
                req.backmsg = "not exist";
                std::cout<<"RUN:"<<"中介者被请求对象"<<modulename.c_str()<<"不存在"<<std::endl;
                nret = -1;
            }
        }
        return nret;
    }
};

#endif

//业务处理基类
#ifndef __BUSSINESS_H
#define __BUSSINESS_H

/*
*@brief:
*@attention:不为业务处理对象添加队列,不支持多线程等
*/


#include "Mediator.h" 

class CBussiness
{
public:
    CBussiness(std::string modulename, CMediator* mediator):m_modulename(modulename), m_mediator(mediator)
    {}
    virtual ~CBussiness()
    {

    }
    virtual int send_notify(std::string& modulename, TRequest& request) = 0;    

    virtual void notify(TRequest& req) = 0;

    std::string notify(int cmdtype)
    {
        std::string cmd = "单播请求";
        if (cmdtype == 0)
            cmd = "广播请求";
        return cmd;
    }
protected:   
    CMediator* m_mediator;  
public:
    std::string m_modulename;
};

#endif

//业务实现类APM

#ifndef __APM_H
#define __APM_H

#include "Bussiness.h"

class CApm:public CBussiness
{
public:
    CApm(std::string modulename, CMediator* mediator):CBussiness(modulename, mediator)
    {}
    int send_notify(std::string& modulename, TRequest& request)
    {
        int nret = m_mediator->delcare(modulename, request);
        if (-1 == nret)
        {
            std::cout<<"RUN:"<<m_modulename.c_str()<<"send to:"<<modulename.c_str()<<"not exist"<<std::endl;
        }
        return nret;
    }
    void notify(TRequest& req)
    {
        std::string cmdtype = CBussiness::notify(req.cmd);
        std::cout<<"RUN APM:"<<cmdtype.c_str()<<":"<<req.sendmsg.c_str()<<" from: "<<req.buss->m_modulename.c_str()<<std::endl;
        req.backmsg = "APM KNOW";   
    }
};

#endif
//业务处理IPM
#ifndef __IPM_H
#define __IPM_H

#include "Bussiness.h"

class CIpm : public CBussiness
{
public:
    CIpm(std::string modulename, CMediator* mediator):CBussiness(modulename, mediator)
    {}
    int send_notify(std::string& modulename, TRequest& request)
    {
        int nret = m_mediator->delcare(modulename, request);
        if (-1 == nret)
        {
            std::cout<<"RUN:"<<m_modulename.c_str()<<"send to:"<<modulename.c_str()<<"not exist"<<std::endl;
        }
        return nret;
    }
    void notify(TRequest& req)
    {
        std::string cmdtype = CBussiness::notify(req.cmd);
        std::cout<<"RUN IPM:"<<cmdtype.c_str()<<":"<<req.sendmsg.c_str()<<" from: "<<req.buss->m_modulename.c_str()<<std::endl;
        req.backmsg = "IPM BUSY, 10 minites later"; 
    }
};

#endif

//业务处理类BSM

#ifndef __BSM_H
#define __BSM_H

#include "Bussiness.h"

class CBsm:public CBussiness
{
public:
    CBsm(std::string modulename, CMediator* mediator):CBussiness(modulename, mediator)
    {}
    int send_notify(std::string& modulename, TRequest& request)
    {
        int nret = m_mediator->delcare(modulename, request);
        if (-1 == nret)
        {
            std::cout<<"RUN:"<<m_modulename.c_str()<<"send to:"<<modulename.c_str()<<"not exist"<<std::endl;
        }
        return nret;
    }
    void notify(TRequest& req)
    {
        std::string cmdtype = CBussiness::notify(req.cmd);
        std::cout<<"RUN BSM:"<<cmdtype.c_str()<<":"<<req.sendmsg.c_str()<<" from: "<<req.buss->m_modulename.c_str()<<std::endl;
        req.backmsg = "BSM DEAL";   
    }
};

#endif

//client调用

#include <iostream>
#include "BussMediator.h"
#include "Bussiness.h"
#include "Ipm.h"
#include "Apm.h"
#include "Bsm.h"


int main(void)
{
    CMediator* mediator = new CBussMediator();
    CBussiness* ipm = new CIpm("IPM", mediator);
    CBussiness* apm = new CApm("APM", mediator);
    CBussiness* bsm = new CBsm("BSM", mediator);

    mediator->add_module("IPM", ipm);
    mediator->add_module("APM", apm);
    mediator->add_module("BSM", bsm);

    std::string tomodulename = "all";
    TRequest ipmreq;
    ipmreq.cmd = 0;
    ipmreq.sendmsg = "IPM RUN";
    ipmreq.buss = ipm;      
    ipm->send_notify(tomodulename, ipmreq);

    std::cout<<"RUN:IPM"<<"back msg:"<<ipmreq.backmsg.c_str()<<std::endl;

    tomodulename = "APM";
    ipmreq.cmd = 1;
    ipmreq.sendmsg = "wait for you";
    ipm->send_notify(tomodulename, ipmreq);
    std::cout<<"RUN:IPM"<<"back msg:"<<ipmreq.backmsg.c_str()<<std::endl;

    tomodulename = "BSM";
    TRequest apmreq;
    apmreq.cmd = 1;
    apmreq.sendmsg = "hello bsm";
    apmreq.buss = apm;
    apm->send_notify(tomodulename, apmreq);
    std::cout<<"RUN:APM"<<"back msg:"<<apmreq.backmsg.c_str()<<std::endl;

    tomodulename = "kitty";
    TRequest bsmreq;
    bsmreq.cmd = 1;
    bsmreq.sendmsg = "hello kitty";
    bsmreq.buss = bsm;
    bsm->send_notify(tomodulename, bsmreq);
    std::cout<<"RUN:BSM"<<"back msg:"<<bsmreq.backmsg.c_str()<<std::endl;

    delete apm;
    delete bsm;
    delete ipm;
    delete mediator;

    return 0;
}

5.设计模式结语
好快设计模式就这样结束了,有部分模式并没有介绍如:单例,装饰,迭代器,享元等,一部分是认为这部分模式太简单了,另外则是对自身而言用的概率太低了,所以也就不总结了。
感觉设计模式还是挺重要的,能够让自身的程序在结构上有很大的提高,编程的思想上也有很大的促进。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值