Chain Of Responsibility Pattern

The Chain of Responsibility pattern (CoR) suggests a low degree of coupling between an object that sends out a request and the set of potential request handler objects.

The first object in the chain receives the request and decides either to handle the request or to pass it on to the next object in the chain. The request flows through all objects in the chain one after the other until the request is handled by one of the handlers in the chain or the request reaches the end of the chain without getting processed.

  • The set of potential request handler objects and the order in which these objects form the chain can be decided dynamically at runtime.
  • There may be different sets of handler objects for different types of requests.
  • In Java all handlers should implement a common interface or be subclasses of a common abstract parent class.
  • The client object and handlers have no idea of each other.
  • An example is Servlet filters.
  • The next handler in the chain can be chosen in many different ways. See the following examples.

Structure

Class Structure:

chain1.gif

Object Structure:

chain2.gif

Examples

EXAMPLE 1: Base handler is responsible for creating the next handler:

public abstract class HandlerBase {
    private HandlerBase successor;
        public void handleRequest(SomeRequestObject sro) {
            if ( based on some conditions create the new successor )
                    successor.handleRequest(sro);
       }
}
 
public class ConcreteHandler extends HandlerBase {
    public void handleRequest(SomeRequestObject sro) {
            if(someCondition)
            super.handleRequest(sro);
    }
}

EXAMPLE 2: Each handler is responsible for selecting the next handler:

public abstract class HandlerBase {
    abstract void handleRequest(SomeRequestObject sro);
    abstract HandlerBase setNextHandler(HandlerBase);
}
 
public class ConcreteHandler extends HandlerBase {
 
    public void handleRequest(SomeRequestObject sro) { 
        ...
        if (condition) {
            HandlerBase next = getNextHandler();
            next.handleRequest(sro);    
        }
    }
 
    public HandlerBase getNextHandler(){
        return theNextHandler;
    }
}

In some cases the flow of handing can be defined outside of hadlers or even in Client:

public void defineFlow() {
    handler1 = new Handler1();
    handler2 = new Handler2();
    handler3 = new Handler3();
 
    handler1.setNextHandler(handler2);
    handler2.setNextHandler(handler3);
  }

Also see Apache Chain: http://commons.apache.org/chain/index.html

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License