“超级”责任链模式

使用的模式


    责任链
    命令
    享元


作用

责任链

负责主流程

享元


共享所有处理单元的数据,比如命令枚举和全局处理单元
使用享元,便于处理
不使用享元,便于维护。

命令


替换主流程中的一块

使用场景


不是单一的处理场景,处理场景中长出了分支的情况
A->B->C->D->END
    ->B1 //A可以到B,B1,B2然后继续处理
    ->B2->END //处理了B2之后就停止了
    
A->B->C->D->END
        ->C1->D->B1 //可以在B之后处理C1,然后C1可以从D跳到B1去

**我们只有一个主处理链就是A->B->C->D->END,其余的你可以理解为可以拆卸的模块可以随便拼装**

 解析


责任链:A->B
->C->D
享元:原始数据(以及上一次处理之后的数据):srcData 目标数据(最后用户可以get的数据)dstData
命令:X,Y,Z

enum cmd {
    X 0x0001
    Y 0x0002
    Z 0x0003
    N 0x0010
}
void put(srcData)
virtual cmd exec() = 0; //处理接口
void get(dstData)

返回N时,正常执行
在运行到B时,返回一个X,那么替换C执行X。然后根据X的返回命令来继续执行


DEMO

#pragma once

#include <iostream>
#include <memory>
#include <unordered_map>

enum CMD {
    NORMALL     = 0x0000,//正常执行链条
    CMD_END     = 0x0001,//命令链条结束
    END         = 0x0002,//责任链结束

    HELLO       = 0x0100,
    WORLD       = 0x0101
};

class AbstractHandle
{
public:
    virtual ~AbstractHandle() = default;
    bool run(const std::string &src,std::string &dst)
    {
        bool ret = false;
        CMD cmd = END;
        std::string allSrc = src+dst;//累加输入,上一次的输出将作为下一次的输入
        ret = exec(allSrc,dst,cmd);

        if(!ret)
            return false;
        switch (cmd) {
        case NORMALL:
            if(next)
                ret = next->run(allSrc,dst);
            break;
        case CMD_END:
            if(next)
                if(next->next)
                    ret = next->next->run(allSrc,dst);
            break;
        case END:
            break;
        default:
            if(more.find(cmd) != more.end()) {
                more[cmd]->set_next(next);//替换责任链上原来的处理器
                ret = more[cmd]->run(allSrc,dst);
            }
            break;
        }

        return ret;
    }

    void set_next(std::shared_ptr<AbstractHandle> next)
    {
        this->next = next;
    }
    void add_more(CMD cmd,std::shared_ptr<AbstractHandle> newOne)
    {
        more[cmd] = newOne;
    }
protected:
    virtual bool exec(const std::string &srcData,std::string &dstData, CMD &cmd) = 0;
    std::shared_ptr<AbstractHandle> next = nullptr;
    ///有两种写法,一种是static作为全部子类公有的,还有一种是某一个子类私有的。
    /// 写法一,static。把add_more作为static方法,把more作为全局变量,便于注册和使用
    /// 写法二,私密性和针对性更强,便于维护和修改
    /// 这里使用的是写法二
    std::unordered_map<CMD,std::shared_ptr<AbstractHandle>> more;
};

class N1:public AbstractHandle
{
    virtual bool exec(const std::string &srcData,std::string &dstData, CMD &cmd) final
    {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
        dstData += __PRETTY_FUNCTION__;
        cmd = NORMALL;
        return true;
    }
};

class N2:public AbstractHandle
{
    virtual bool exec(const std::string &srcData,std::string &dstData, CMD &cmd) final
    {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
        dstData += __PRETTY_FUNCTION__;
        cmd = HELLO;
        return true;
    }
};

class N3:public AbstractHandle
{
    virtual bool exec(const std::string &srcData,std::string &dstData, CMD &cmd) final
    {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
        dstData += __PRETTY_FUNCTION__;
        cmd = NORMALL;
        return true;
    }
};

class N4:public AbstractHandle
{
    virtual bool exec(const std::string &srcData,std::string &dstData, CMD &cmd) final
    {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
        dstData += __PRETTY_FUNCTION__;
        cmd = END;
        return false;
    }
};

class HELLO:public AbstractHandle
{
    virtual bool exec(const std::string &srcData,std::string &dstData, CMD &cmd) final
    {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
        dstData += __PRETTY_FUNCTION__;
        cmd = WORLD;
        return true;
    }
};

class WORLD:public AbstractHandle
{
    virtual bool exec(const std::string &srcData,std::string &dstData, CMD &cmd) final
    {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
        dstData += __PRETTY_FUNCTION__;
        cmd = CMD_END;
        return true;
    }
};

class Handle
{
public:
    ~Handle()
    {
        deinit();
    }

    void init()
    {
        n1 = std::make_shared<N1>();
        n2 = std::make_shared<N2>();
        n3 = std::make_shared<N3>();
        n4 = std::make_shared<N4>();
        hello = std::make_shared<class HELLO>();
        world = std::make_shared<class WORLD>();

        n1->set_next(n2);
        n2->set_next(n3);
        n3->set_next(n4);

        n2->add_more(HELLO,hello);
        hello->add_more(WORLD,world);
    }

    void run(const std::string &src,std::string &dst)
    {
        n1->run(src,dst);
    }
private:
    std::shared_ptr<AbstractHandle> n1 = nullptr;
    std::shared_ptr<AbstractHandle> n2 = nullptr;
    std::shared_ptr<AbstractHandle> n3 = nullptr;
    std::shared_ptr<AbstractHandle> n4 = nullptr;
    std::shared_ptr<AbstractHandle> hello = nullptr;
    std::shared_ptr<AbstractHandle> world = nullptr;

    void deinit()
    {

    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值