责任链模式(Chain of Responsibility Pattern)

 
责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。

在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。


常用场景1)
有一个请求数据,有一组handler, 其中的某一个handler可以用来处理该请求,可以将所有的handler连成一个chain,数据发送给第一个handler,其判断自己能否处理该数据,如果能则处理,并结束,否则, 调用下一个handler的处理函数,以此类推。
或者
客户发送了一个数据,该数据需要被各个环节进行检查,只有前面的检查通过后才进入下一个环节,可以将各个环节的检查函数抽象出来,将各个环节按照顺序连成一个链子。


常用场景2)
UI系统, 用户触发某个控件的一个signal, 该信号从子控件传递到上层父控件,层层前进,直到到达能够处理该signal的控件。

 

 

举例C++

Interface类为纯虚类定义公共的接口,ComponentBase类继承自接口类,定义各个具体的Component类的公共的部分, DogComponent为一个具体的类。

main函数中定义的链条: DogComponent对象 -> MonkeyComponent对象->ChickenComponent对象

#pragma once
#include <string>
#include <iostream>
#include <vector>

using namespace std;


/**
 * The interface declares a method for building the chain of handlers.
 * It also declares a method for executing a request.
 */
class Interface {
public:
    Interface() {}
    virtual ~Interface() {};

    virtual Interface* setNextComponent(Interface* p) = 0;
    virtual string handle(string sRequestData) = 0;
};

/**
 * The default chaining behavior can be implemented inside a base handler class.
 */
class ComponentBase :public Interface {
public:
    ComponentBase():
        next(nullptr){

    }
    virtual ~ComponentBase() {

    }
    virtual string handle(string sRequestData) override{
        if (next) {
            return next->handle(sRequestData);
        }
        return "";
    }

    Interface* setNextComponent(Interface* nextComp) {
        next = nextComp;
        // Returning a handler from here will let us link handlers in a convenient way like this:
        // $monkey->setNext($squirrel)->setNext($dog);
        return nextComp;
    }
    Interface* getNextComponent() const {
        return next;
    }
protected:
    Interface* next;
};


/**
 * All Concrete Handlers either handle a request or pass it to the next handler
 * in the chain.
 */

class DogComponent:public ComponentBase {
public:
    DogComponent() {}
    virtual ~DogComponent() {}

    virtual string handle(string sRequestData) override {
        if ("Shit" == sRequestData) {
            return sRequestData + " was eated by Dog!\n";
        }
        else {
            return ComponentBase::handle(sRequestData);
        }
    }
};

class MonkeyComponent :public ComponentBase {
public:
    MonkeyComponent() {}
    virtual ~MonkeyComponent() {}

    virtual string handle(string sRequestData) override {
        if ("Banana" == sRequestData) {
            return sRequestData + " was eated by Monkey!\n";
        }
        else {
            return ComponentBase::handle(sRequestData);
        }
    }
};

class ChickenComponent :public ComponentBase {
public:
    ChickenComponent() {}
    virtual ~ChickenComponent() {}

    virtual string handle(string sRequestData) override {
        if ("Rice" == sRequestData) {
            return sRequestData + " was eated by Chicken! \n";
        }
        else {
            return ComponentBase::handle(sRequestData);
        }
    }
};

/**
 * The client code is usually suited to work with a single handler. In most
 * cases, it is not even aware that the handler is part of a chain.
 */
void ClientCode(Interface &handler, const string& requestData) {

    const std::string result = handler.handle(requestData);
    if (!result.empty()) {
        std::cout << "  " << result;
    }
    else {
        std::cout << "  " << requestData << " was left untouched.\n";
    }

}

int main() {
    DogComponent* pDog = new DogComponent();
    MonkeyComponent* pMonkey = new MonkeyComponent();
    ChickenComponent* pChicken = new ChickenComponent();

    pDog->setNextComponent(pMonkey)->setNextComponent(pChicken);

    //入参也可时chain中间的某个元素,例如*pMonkey。
    ClientCode(*pDog, "Shit");

    return 1;
}

 

Ref:

https://refactoring.guru/design-patterns/chain-of-responsibility
https://refactoring.guru/design-patterns/chain-of-responsibility/cpp/example

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

First Snowflakes

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值