3

In the 'Chain of Responsibility(COR)' pattern, we create a chain of handlers. Pass the request to the first in the chain. It tries to handle it. If it cannot, it forwards the request to the next in the chain and so on. Eg. Handler1 = new ConcreteHandler1(); handler1.handle

public class ConcreteHandler1
    public void handle() {
        if(can handle)
            handle the request
        else 
            concreteHandler2.handle(); 
    }

Can't we simply create a list of handlers and accomplish the same in a for loop?

for(Handler handler : handlers) {
    if(handler can handle the request)
        handle
}

We will create handlers list in the same way we create the chain.

  1. In what way is this for loop inferior to COR? Is n't COR just an overkill?
  2. Are there scenarios where this for loop is better and others where COR is better? In your answer - it will be great if you can first answer these questions with Yes/No before going into the detailed explanation.

I know there is a post on this already - What are the advantages of chain-of-responsibility vs. lists of classes? but it does n't clarify my doubts.

BlackPearl
  • 1,662
  • 1
  • 8
  • 16
Praveen Nvs
  • 331
  • 3
  • 14
  • Consider encapsulation and have a look at internal versus external iteration. Also, at least pretend you didn’t straight up post your homework here. In your question - it will be great if you can not ask for a specific answer format that is suspiciously close to exams. – MisterMiyagi May 04 '19 at 07:14
  • 2
    The CoR pattern does much more than just deciding if one handler can or cannot handle a request. Every handler does whetever it wants to do with the request, **then** decides if the next handler should or shouldn't get the request, **then** can decide to do something else with the request after the next handler has handled the request. – JB Nizet May 04 '19 at 07:55
  • Yeah.. I got it but can't the same be done with a for loop ? Are you saying that with COR pattern , multiple handlers can handle the request (partially processing it ) and the same cannot be done with for loop? – Praveen Nvs May 04 '19 at 08:07
  • It would be much harder to keep the same flexibility: instead of letting each handler do whatever thay want to do inside a single method, the handler would have to tell the for loop if they want to preprocess the request, to prostprocess it, to let the next handler process it, what to do in case of an exception, etc. etc. Patterns do not exist to solve a problem that can't be solved in any other way. they're there to provide an elegant, easy to recognize solution to common problems. – JB Nizet May 04 '19 at 09:44
  • @JBNizet - Good. I am starting to love this discussion. Hope it ends in clarifying my doubts...- In COR, where are pre and post processings done? It happens inside the handle method.. right ? ConcreteHandler1 extends AbstractHandler{ handle() { ...pre-process ...perform some logic ...post-process } } Knowing how pre or post processing is done in COR can help in understanding why it is more elegant than for loop. Can you throw some light on how it is done? As far as I know, in COR, we will have just one handle method that does everything. – Praveen Nvs May 04 '19 at 11:11
  • You got it: pre processing is just the set of instructions coming before the call to the next handler, and post processing is just the set of instructions coming after the call to the next handler. – JB Nizet May 04 '19 at 11:24
  • @JBNizet The picture is getting clearer but there are some still some blurry areas.. But,even in a for loop, you can simply invoke handle method which in turn does pre and post steps right too in addition to the actual logic. Right? handle method takes care of everything. I understand COR clearly but trying to figure out the area where COR shines and for loop falls short. – Praveen Nvs May 04 '19 at 12:00
  • Try doing it, and you'll see that you're missing something. – JB Nizet May 04 '19 at 12:01
  • @JBNizet Got it now. It is not that pre and post cannot be done using for loop but doing through recursion(COR) is a far simpler and a natural way. Matt's answer confirms this..But, I can't deny that discussion with you was of great help. Thanks ! – Praveen Nvs May 04 '19 at 13:15

1 Answers1

7

The chain is organized recursively just so that a handler can:

  • Do some work before the next handler runs, including modifying the input to the next handler; AND
  • Do some work after the next handler runs, including processing or modifying the output of the next handler before it is returned to the previous handler; AND
  • Use information it stored before the next handler ran to affect the output afterwards.

Recursion is just the simplest and most straightforward way to arrange all that. To allow similar functionality without recursion would require more callbacks and a more complicated handler life cycle.

When handlers do not produce any output, like HTML event handlers, doing work both before and after is unnecessary. In these cases event handlers are usually called iteratively as you suggest.

Matt Timmermans
  • 53,709
  • 3
  • 46
  • 87
  • "Recursion is just ......." - Got it. I too think it is possible to do this using for loop. (I wanted confirmation on this and your answer gives it) but I agree that recursion looks like a natural and a straightforward way. - In this scenario, COR really shines ... "When handlers do not produce ........ " - Wonderful. In this scenario - iterative call too is good. This just shows that COR does not beat iterative loop all the time. Thank you Matt ! I thought over these paragraphs for some time and it is crystal-clear. Wonderfully written.. – Praveen Nvs May 04 '19 at 14:35