04 May 2012

Behavioral Design Pattern –  Chain of Responsibility


Behavioral patterns are concerned with the interaction and responsibility of objects. They help make complex behavior manageable by specifying the responsibilities of objects and the ways they communicate with each other.

The following Behavioral patterns are described by GoF:
  • Chain of Responsibility
  • Command
  • Interpreter
  • Iterator
  • Mediator
  • Memento
  • Observer
  • State
  • Strategy
  • Template Method
  • Visitor

Chain of Responsibility 

The Chain of Responsibility pattern’s intent is to avoid coupling the sender of a request to its receiver by giving multiple objects a chance to handle the request. The request is passed along the chain of receiving objects until an object processes it. shows the UML.

The Chain of Responsibility pattern’s intent is to avoid coupling the sender of a request to its receiver by giving multiple objects a chance to handle the request. The request is passed along the chain of receiving objects until an object processes it. shows the UML.



Figure  UML for the Chain of Responsibility pattern
Benefits  Following are the benefits of using the Chain of Responsibility pattern:
  • It reduces coupling.
  • It adds flexibility when assigning responsibilities to objects.
  • It allows a set of classes to act as one; events produced in one class can be sent to other handler classes within the composition.
Applicable Scenarios  The following scenarios are most appropriate for the Chain of Responsibility pattern:
  • More than one object can handle a request and the handler is unknown.
  • A request is to be issued to one of several objects and the receiver is not specified explicitly.
  • The set of objects able to handle the request is to be specified dynamically.
J2EE Technology Feature  The J2EE technology feature associated with the Chain of Responsibility pattern is RequestDispatcher in the servlet/JSP API.

Example Code  The following example Java code demonstrates the Chain of Responsibility pattern:



package j2ee.architect.ChainOfResponsibility;

public class ChainOfResponsibilityPattern {
public static void main(String[] args) {
System.out.println("Chain Of Responsibility Pattern Demonstration.");
System.out.println("———————————————————————");
try {
// Create Equity Order request.
System.out.println("Creating Equity Order request.");
Request equityOrderRequest = new Request(Request.EQUITY_ORDER);
// Create Bond Order request.
System.out.println("Creating Bond Order request.");
Request bondOrderRequest = new Request(Request.BOND_ORDER);
// Create a request handler.
System.out.println("Creating 1st handler.");
HandlerIF handler = new ConcreteHandler1();
// Process the Equity Order.
System.out.println("Calling 1st handler with Equity Order.");
handler.processRequest(equityOrderRequest);
// Process the Bond Order.
System.out.println("Calling 1st handler with Bond Order");
handler.processRequest(bondOrderRequest);
} catch (Exception e) {
System.out.println(e.getMessage());
}
System.out.println();
}
}

package j2ee.architect.ChainOfResponsibility;
public class ConcreteHandler1 implements HandlerIF {
public void processRequest(Request parm) {
// Start the processing chain here...
switch (parm.getType()) {
case Request.EQUITY_ORDER: // This object processes equity orders
handleIt(parm);          // so call the function to handle it.
break;
case Request.BOND_ORDER:   // Another object processes bond orders so
System.out.println("Creating 2nd handler."); // pass request along.
new ConcreteHandler2().processRequest(parm);
break;
}
}
private void handleIt(Request parm) {
System.out.println("ConcreteHandler1 has handled the processing.");
}
}
package j2ee.architect.ChainOfResponsibility;
public class ConcreteHandler2 implements HandlerIF {
public void processRequest(Request parm) {
// You could add on to the processing chain here...
handleIt(parm);
}
private void handleIt(Request parm) {
System.out.println("ConcreteHandler2 has handled the processing.");
}
}
package j2ee.architect.ChainOfResponsibility;
public interface HandlerIF {
public void processRequest(Request request);
}
package j2ee.architect.ChainOfResponsibility;
public class Request {
// The universe of known requests that can be handled.
public final static int EQUITY_ORDER = 100;
public final static int BOND_ORDER   = 200;
// This objects type of request.
private int type;
public Request(int parm) throws Exception {
// Validate the request type with the known universe.
if ((parm == EQUITY_ORDER) || (parm == BOND_ORDER))
// Store this request type.
this.type = parm;
else
throw new Exception("Unknown Request type "+parm+".");
}
public int getType() {
return type;
}
}