c ++ design patterns - duty chain.

Motivation
the software building process, request a plurality of objects may be processed, but only one receiver each request at run time, if the display is specified will be necessary to bring the tight coupling of the recipient's request.
How to make the sender of the request need not specify a particular recipient? Let the recipient's own request at runtime to process the request, so that both decoupled.
Mode is defined
so that more than one object a chance to handle the request, in order to avoid the coupling between the sender and receiver of the request. These objects together into a chain, and pass the request along the chain until an object handles it so far.
Structure
QQ picture 20200210213627.png
example

enum class RequestType
{
    REQ_HANDLER1,
    REQ_HANDLER2,
    REQ_HANDLER3
};

class Reqest
{
    string description;
    RequestType reqType;
public:
    Reqest(const string & desc, RequestType type) : description(desc), reqType(type) {}
    RequestType getReqType() const { return reqType; }
    const string& getDescription() const { return description; }
};

class ChainHandler{
private:
    ChainHandler *nextChain;
    void sendReqestToNextHandler(const Reqest & req)
    {
        if (nextChain != nullptr)
            nextChain->handle(req);
    }
protected:
    virtual bool canHandleRequest(const Reqest & req) = 0;
    virtual void processRequest(const Reqest & req) = 0;
public:
    ChainHandler() { nextChain = nullptr; }
    void setNextChain(ChainHandler *next) { nextChain = next; }
    
   
    void handle(const Reqest & req)
    {
        if (canHandleRequest(req))
            processRequest(req);
        else
            sendReqestToNextHandler(req);
    }
};


class Handler1 : public ChainHandler{
protected:
    bool canHandleRequest(const Reqest & req) override
    {
        return req.getReqType() == RequestType::REQ_HANDLER1;
    }
    void processRequest(const Reqest & req) override
    {
        cout << "Handler1 is handle reqest: " << req.getDescription() << endl;
    }
};
        
class Handler2 : public ChainHandler{
protected:
    bool canHandleRequest(const Reqest & req) override
    {
        return req.getReqType() == RequestType::REQ_HANDLER2;
    }
    void processRequest(const Reqest & req) override
    {
        cout << "Handler2 is handle reqest: " << req.getDescription() << endl;
    }
};

class Handler3 : public ChainHandler{
protected:
    bool canHandleRequest(const Reqest & req) override
    {
        return req.getReqType() == RequestType::REQ_HANDLER3;
    }
    void processRequest(const Reqest & req) override
    {
        cout << "Handler3 is handle reqest: " << req.getDescription() << endl;
    }
};

int main(){
    Handler1 h1;
    Handler2 h2;
    Handler3 h3;
    h1.setNextChain(&h2);
    h2.setNextChain(&h3);
    
    Reqest req("process task ... ", RequestType::REQ_HANDLER3);
    h1.handle(req);
    return 0;
}

Summary points
1. duty chain applications that "there may be a request to multiple recipients, but in the end the real recipient of only one", then the coupling request sender and the recipient may be a "change vulnerability" symptoms, the purpose of the chain of responsibility is to decouple the two, in order to better respond to change.
2. After the application of the chain of responsibility pattern, the object will be assigned duties more flexibility. We can dynamically add / change request processing functions at runtime.
3. If the request to the end of the chain of responsibility is still not addressed, there should be a reasonable default mechanism. It is also accepted responsibility for each object, rather than the responsibility of issuing the request object.

Guess you like

Origin www.cnblogs.com/Redwarx008/p/12292936.html