In this article we are going to learn about Chain of Responsibility Design Pattern.
- What is Chain of Responsibility pattern?
- What are the principles? How to implement in code?
- Where we may use that?
In this article I have mainly used Java with eclipse. I have added c# implementation with VS2010 also.
What is Chain of Responsibility pattern?
In OO design, if we find a situation when we have functionality to perform and we do not know specifically who is going to perform the task then its the time to use Chain of Responsibility pattern. Chain of Responsibility is a behavioral pattern that allow a request client to send its request without knowing who is going to do that. It allows an object to send a command without knowing what object will receive and handle it.
For example , Comparing to real life, suppose you are junior software developer and you are resigning from you company.
What you do, just submit your resignation letter to your superior (maybe a software engineer or a senior software engineer).
And, you may not need to know who is going to process, though it can be processed by CEO/CTO(some companies)/COO/HR officer/HR Manager or even a office Admin personal.
So, in this real life situation we may not know who will execute resigning and we just give that to the superior pool, among them any one can do that. And, what will happen, who ever gets your resign letter, he will pass to his superior, and his superior will pass to another superior and this will be continued until the task is done.
Same things happens in real life object. An object contain a task to be done, he send it to the workers(chain of workers related to each other) and he get it done.
Similar to , if an event is generated by one object and needs to be handled by another object( who actually related to a chain of objects that performs similar tasks) then the worker object will take the event among chain and it will be performed by the object which can do the task.
So, let’s think how to solve and implement the problem. In Chain of Responsibility, we are going to make a chain of objects who are actually set of workers performs a particular work.
They have common behavioral chain that allows them to talk/collaborate to each other. And they have common behaviors. So, we will need
- An abstract class or common interface of all worker classes in a chain contains common behaviors.
- A defining method chain that allows others to create a chain among those objects.
- An client/user object /task which can be assign any one of the chain.
- A method as chain behavior that controls work execution(a condition allows any object of the chain to do work or pass to next member of the chain,more like as choosing successor)
UML
Applying Chain of Responsibility
Step 1
Defining an abstract class that contains method for working and for chaining. I have used like this
public abstract class MyHandler {
protected MyHandler myNextHandler;
//to pass the request to successor, this will be used for making chain
public void setMyNextHandler(MyHandler successor)
{
myNextHandler = successor;
}
// This method actually responsible for doing task
public abstract void doThis(Task task);
}
This contains the chaining and performing task behavior.
Step 2
Task class is the simple client requested parameter that contains values based on which tasks are varied.
public class Task {
private int myValue;
private String description;
public Task(int value, String des) {
myValue = value;
description = des;
}
public int getValue()
{
return myValue;
}
public String getDescription(){
return description;
}
}
Step 3
Now the chain classes. In the example, I have set condition like, if the value is <0, then one class will do work, if ==0 then 2nd one, and lastly if >0 then the third one. I have experimentally added forth class as condition ==4 but it will never be used as class three can handle the same value(as >0).
So, lets define class one of the chain
public class RealHandlerOne extends MyHandler {
public void doThis(Task task){
if(task.getValue()<0)
{
System.out.println("This is Handler One and value = "+ task.getValue());
}else{
myNextHandler.doThis(task);
}
}
}
Step 4
And , the 2nd class and third class.
public class RealHandlerTwo extends MyHandler {
public void doThis(Task task){
if(task.getValue()==0)
{
System.out.println("This is Handler two and value = "+ task.getValue());
}
else{
myNextHandler.doThis(task);
}
}
}
public class RealHandlerTwo extends MyHandler {
public void doThis(Task task){
if(task.getValue()==0)
{
System.out.println("This is Handler two and value = "+ task.getValue());
}
else{
myNextHandler.doThis(task);
}
}
}
Step 5
And then we need someone one make the chain among RealHandlerOne, RealHandlerTwo, RealHandlerThree and send the request inside the Task object to any of the instance of those classes.
BTW, if you want , you can use this interface in place of abstract class. Just we have to add private MyHandler myNextHandler in each real handler class.
public interface IMyHadler {
void setMyNextHandler(MyHandler successor);
void doThis(Task task);
}
Sources
Java Example :
You will find another class Program which actually executes as client that send request inside task object. I have use Main so that I can run and show the results in console output.
For a framework, you may not need to put it inside Main method. So you will find
- Object creation of RealHandlerOne, RealHandlerTwo, RealHandlerThree
MyHandler handler1 = new RealHandlerOne();
MyHandler handler2 = new RealHandlerTwo();
MyHandler handler3 = new RealHandlerThree();
MyHandler handler4 = new RealHandlerFour();
-
Object creation Task for using as Class
-
Making chain among the objects of handler classes.
handler1.setMyNextHandler(handler2);
handler2.setMyNextHandler(handler3);
handler3.setMyNextHandler(handler4);
handler4.setMyNextHandler(handler1);
- Calling for a task of any of chained handler objects.
In every RealHandler classes , doThis method actually do the work (in here console print) depend on condition.
If it can not do the work, it send the request(task object) as to its next member of the chain(as next handler)
You may see experimentally created RealHandlerFour class that proves, if any handler can do the work it never pass through to another handler.
I have added interface in case you use the interface instead of abstract class .
Noticeable point : Take a look at the request, every time only handler1.doThis(); perform the task.
Now, if you Run as java application, you will see that in console.
Here, when value is -100, RealHandlerOne perform the task ,
when value is = 0, RealHandlerTwo the task,
when value is >0 (1,2,3,4) , RealHandlerThree the task.
C# Example : Notes :
- I have used property NextHandler in place of setMyNextHandler(MyHandler successor)
- I avoid experimentally created RealHandlerFour class in here (which I have used in java example)
- I have renamed my handlers objects as worker in Main.
- Console.Readline() is only for making console results visible.
Befits :
- We can abstract presence of a particular class who actually does the work.
- We can extend functionality by adding a member in the chain.
- We can use when a set of objects do small pats of a big task.
- It is loose coupled , so very good for framework design with maximum level of abstraction.