E
E
egorggegor2019-08-20 16:40:36
OOP
egorggegor, 2019-08-20 16:40:36

Why doesn't (Chain of Responsibilty) work?

Ku
Implemented a chain of responsibility pattern, but when testing, a problem with threads pops up, does anyone know how to deal with this?
(The problem is marked in the code, the tests that revealed the problem in the main)

class Handler {
public:
    Handler(): next(nullptr) {};
    virtual ~Handler() {};
    virtual void HandleRequest(int data) {
        if (next) {
            this->next->HandleRequest(data);
        }
    }
    void SetNextHandler(Handler* next_handler) {  //Здесь вроде проблема
        if (next) {
            this->SetNextHandler(next_handler);
        } else {
            this->next = next_handler;
        }
    }
public:
    Handler* next;
};

class ConcreteHandler1 : public Handler {
public:
    void HandleRequest(int data) {
        //if can handle it do it
            //implementation of HadleRequest
        //else
        std::cout << "ConcreteHandler1" << std::endl;
        Handler::HandleRequest(data);
    }
};

class ConcreteHandler2 : public Handler {
public:
    void HandleRequest(int data) {
        //if can handle it do it
            //implementation of HadleRequest
        //else
        std::cout << "ConcreteHandler2" << std::endl;
        Handler::HandleRequest(data);
    }
};

int main(int argc, const char * argv[]) {
    Handler* handler = new Handler;
    int data;
    handler->SetNextHandler(new ConcreteHandler1());
    handler->SetNextHandler(new ConcreteHandler2());
    handler->HandleRequest(data);
    return 0;
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
L
lorc, 2019-08-20
@egorggegor

I suspect it should be like this:

void SetNextHandler(Handler* next_handler) {  
        if (next) {
            next->SetNextHandler(next_handler); // <- next, не this
        } else {
            this->next = next_handler;
        }
    }

Otherwise, you end up with an infinite recursion.
But in general, this is not the most optimal algorithm, because the complexity of adding a new handler is O (N), although one could do O (1) if the order of the call is not important.
And yet, it would be possible to have a virtual function that will only take care of handling. This will make the code more robust and avoid Handler::HandleRequest(data);at the end of each handler.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question