Avijeet Dash & Satyabrata Dash
Intent
one object, a chance to handle the request. Chain the receiving objects and pass
on the request along the chain until an object handles it.
In 30 Seconds
The catch in this pattern is "it lets you send requests to an object
implicitly through a chain of candidate objects". Any Candidate object
might fulfill the request depending on the run time conditions. The number of
candidates is open-ended and you can select which candidates participate in the
chain at run time.
The Chain is generally achieved by using inheritance to form a tree structure
of all the candidate objects from very specific types at leaf nodes to very
general one at root level. An example of this pattern: In Java1.0 the
event-handling model was based on this pattern.
All the GUI elements capable of generating an event (e.g. MouseClick,
MouseMove etc) were from the parent class Component. Any event not handled by
(for instance) a button would automatically be fired to the next level of
container and this continues recursively until it’s handled or ignored in the
whole chain of candidate GUI objects. This model has the drawbacks of making the
system slow and has lesser flexibility. It is slow because an event used to
traverse the whole chain of containers until gets handled. It is less flexible
as every event handling GUI element has to inherit from Component. In Java 1.1
and Java2 the event model was changed to ‘Observer Pattern’ where only
objects interested in an event gets the event when they register a listener for
it.
Motivation
One better example of this pattern is a ‘context-sensitive help system’.
Say you have two buttons in a Print dialog, a Print button and an Ok Button. The
Print Dialog is in an application window.
Now when you need help information on the print button and no specific
information exists, it should show the help information of the immediate context
that’s of the dialog box. So basically the help information is organized in
such a ‘more specific’ to ‘more general’ way that always the immediate
context can handle the request or forward it to a higher level object.
- So the Client that issued the request has no direct reference or explicit
knowledge of the object that ultimately handles the request. - Each object in the chain shares a common interface for handling requests
and for accessing its successor on the chain.
Generally this pattern is used in conjunction with Composite. Composite
builds the chain using inheritance. So the default successor is the parent
class. All of them in the hierarchy support a handleRequest() method. If any
child node doesn’t want to handle the request in a specific way and doesn’t
override handleRequest() then, when a request comes due to inheritance
handleRequest() of the parent class gets executed.
Structure
Context-Sensitive Help System
Click here to view image
Chain Of Responsibility UML diagram
Click here to view image
 Sample Code
/* This is the abstract Handler code */
package chainexample;
import java.lang.*;
public abstract class MyHandler extends java.lang.Object
/** successor is a private variable to hold the next in line for the
Chain of Responsibility
*/
private MyHandler successor = null;
/** integer value of the request that this instance is responsible
for
*/
public int myRequest = 0;
/** The Handler Method is the constructor for the class Handler.
This method constructs a new instance of class Handler and initializes
the successor for this instance to the next instance to be called in
the Chain of Responsibility
@param s This parameter is used to hold the next Handler in the
Chain of Responsibility
@param r This parameter isused to identify which request the instance
will take responsibility for
*/
public void MyHandler(MyHandler s, int r)
{
successor = s; // set successor for this instance to be the
// instance of MyHandler passed in.
myRequest = r; // set the request that this instance is responsible for
}//EndofConstructor MyHandler
/** The MyHandler Method is the default constructor for the class MyHandler.
This method constructs a new instance of class MyHandler and initializes
the successor for this instance to the next instance to be called in
the Chain of Responsibility. In this case there is no parameter accepted
so the defined constructor above is called with a parameter of 'null'
as the next MyHandler in the Chain.
*/
public void MyHandler()
{
this.MyHandler(null,0); // call the defined constructor with a null
instance.
}//EndofConstructor MyHandler
/**
SetSuccessor is a method offered to enable the client to set the
next MyHandler in the Chain.
@param h is of type MyHandler and should be the next Hanlder to call in
the chain if the HandleRequest does not fulfill the request.
*/
public void SetSuccessor(MyHandler h)
{
successor = h;
}//EndofMethod SetSuccessor
/**
HandleRequest is the method that should be called to process or deal
with the responsibility requested. The implementation provided in the
abstract class is a default method offered in the case where the
a subclass does not override this method to provide a concrete
HandleRequest. Note that the specific instance of MyHandle can override
the semantics by returning a unique value for string.
@exception NoSuccessor This exception is raised when the instance of the
MyHandler class has no successor. No attempt is made to determine whether a
successor ever existed for this instance.
@param request This parameter represents a set of requests that the
instance could handle or process. This parameter can and is expected to be
modified to represent the type of request that the instance can handle.
@return String This method returns a text String.
*/
public String HandleRequest(int request) throws NoSuccessor
{
String returnValue = "";
if (successor == null){throw new NoSuccessor("No successor");
} else {
returnValue = successor.HandleRequest(request);
}
return returnValue ;
}//EndofMethod HandleRequest
}//EndofClass MyHandler
/* This is a Concrete Handler */
package chainexample;
public class RequestHandler extends MyHandler
{
String instanceName = "Not set";
public RequestHandler(String name, RequestHandler s, int r){
super.MyHandler(s, r);
instanceName = name;
}
public RequestHandler(String name){
super();
instanceName = name;
}
public String HandleRequest(int request) throws NoSuccessor
{
String returnValue = "";
if (request == this.myRequest) {returnValue = "Handled by " + this.instanceName;
}
else {try {
return super.HandleRequest(request);
}
catch (NoSuccessor e) {returnValue = "No Successor Exception Caught by " +this.instanceName;
}
}
return returnValue;
}// EndOfMethod HandleRequest
}//EndOfClass RequestHandler
Â
Complexities simplified
Implementing the Successor Chain
The successor link can be either a new link or an existing link. An existing
link is the case of the parent class in a part-whole hierarchy. This is simple
and saves space as well. If the tree structure doesn’t reflect the chain of
responsibility, the application needs then different successor links can be
defined.
Representing the Request
The common implementation of handleRequest() would be to call a specific
method i.e. the request is a hard-coded method invocation. To support an
open-ended set of requests the handler function can take in a request code (an
integer or string constant) and dispatch them to appropriate methods. Even
better way to handle the request is to make it an object.
Related Patterns
Chain of responsibility is often applied in conjunction with Composite.