javadesign-patternschain-of-responsibility

Chain of responsibility special scenario


In normal chain of responsibility design pattern implementation, handlers of the request will be added to the chain in a sequential order and will be executed accordingly. However in a special scenario if it's required to skip intermediate handlers and process request in the final handler, will it violate COR design pattern? Please refer the code snippets below. Hope it will clarify this further. Thanks in advance.

public class SomeHandler extends RequestProcessor {

public SomeHandler() {
    super();
}

@Override
public void process(Request request) {
    if (request != null) {
        //Logic to decide request type
        if ("TYPE_ONE".equalsIgnoreCase(request.getType())) {
            //passing to next object in the chain. Multiple chains...
            this.nextRequestProcessor.process(request);
        } else if ("TYPE_TWO".equalsIgnoreCase(request.getType())) {
            //passing to the last object in the chain,skip all the other intermediate objects
            new FinalHandler().process(request);
        }
    }
}

}


Solution

  • This is a bit subjective.

    This handler knows that a certain type of request must be handled by a certain handler1. So, it bypasses the chain and invokes the handler directly. This means that this handler is aware of other (concrete) handlers in the chain (a leak of knowledge).

    Note: Rather than creating a new instance of the handler, you could have had a reference to the final handler instance in SomeHandler.

    Alternatively, you can make this decision before invoking the chain.

    public class Client {
        private RequestProcessor chainOfRequestProcessors;
        private RequestProcessor finalHandler; //instance of FinalHandler
    
        public void process(Request request) {
            if ("TYPE_TWO".equalsIgnoreCase(request.getType())) {
                finalHandler.process(request);
            } else {
                //handle normally
                chainOfRequestProcessors.process(request);
            }
        }
    }
    

    A design pattern is just that. A pattern or a skeletal template for a solution to solve a particular type of problem. It doesn't mean you cannot tweak it and use it in a different way as per your use-case or need (given that you know what you are doing).


    1 You've said ([emphasis mine])

    .... However in a special scenario if it's required to skip intermediate handlers and process request in the final handler ...

    But in your example, the delegation happens in an usual way (by checking the request type). It appears that, in this example, you can simply keep delegating if none of the intermediate handlers can process request type TYPE_TWO. But I guess there is something more to determine when we should go straight to the last handler and the example has been simplified.