Chain Of Responsibility
Chain Of Responsibility Pattern creates a chain of objects that examine a request. Each object in turn examines the request and handles it if it can, otherwise passes it on to the next object in the chain. So each object in the chain acts as a handler.
The object that ultimately handles the request is unknown explicitly to the sender object that sends the request. By this way we are using chain of responsibility pattern to decouple the sender of the request and its receivers.
Each object on the chain shares a common interface for handling requests and for accessing its successor on the chain.
Receipt is not guaranteed - a request could fall off the end of the chain without being handled.
The Java Servlet filter framework is an example of chain of resposibility design. Note that the chain.doFilter() is the method that should be called to make the chain roll. If the subclass missed it, the whole chain would be stopped or blocked.
Java exception handling is another example of chain of responsibility design. When an error occurs, the exception call will look for a handling class. If there is no handler, the super Exception class will be called to throw the exception. Otherwise, the handler class will handle it. Processing stops after an event is handled.
Chain of responsibility simplifies object interconnections.Instead of senders and receivers maintaining references to all candidate receivers,each sender keeps a single reference to the head of the chain,and each receiver keeps a single reference to the immediate successor in the chain.
Chain Of Responsibility uses Command Pattern to represent requests as objects.
Chain of Responsibility is often applied in conjunction with CompositePattern.There,a component's parent act as its successor.
abstract class Car {
public double price = 5.5;
public String color = "Silver";
public String size = "Small";
// The Next Element in the Chain of Responsibility
protected Car next;
protected Car searchNext(Car car) {
next=car;
return this;
}
public void trail(String performance) {
if(price < 10 && performance.equalsIgnoreCase("Satisfactory")){
buyCar(performance);
}
else{
if(next!=null)
next.trail(performance);
}
}
abstract protected void buyCar(String performance);
}
public class Innova extends Car{
public Innova(double price,String color,String size) {
this.price = price;
this.color = color;
this.size = size;
}
protected void buyCar(String performance) {
System.out.println("Liked Innova ... performance... "+performance);
}
}
public class Toyota extends Car{
public Toyota(double price,String color,String size) {
this.price = price;
this.color = color;
this.size = size;
}
protected void buyCar(String performance) {
System.out.println(" Liked Toyota ... performance... "+performance);
}
}
public class SearchCars {
public static void main(String[] args) {
Car car=new Toyota(10.5,"black","big").searchNext(new Innova(8.5,"silver","medium"));
car.trail("Satisfactory");
}
}
When To Use:
1. Use Chain Of Responsibility Pattern when you want to give more than one object a chance to handle a request and the actual handler is not known in advance.
2. Commonly used in windows systems to handle events like mouse clicks and keyboard events.
3. When you want to avoid coupling the sender of a request to its receiver.
Advantages:
1. Decouples the sender of the request and its receivers.
2. Simplifies your object as it doesn't have to know about the chain structure and keep direct references to its members.
3. Allows you to add or remove responsibilities dynamically by changing the members or order of the chain.
Example 1
In designing the software for a system that approves the purchasing requests.
In this case, the values of purchase are divided into categories, each having its own approval authority. The approval authority for a given value could change at any time and the system should be flexible enough to handle the situation.
The Client in the example above is the system in need of the answer to the approval. It sends a request about it to an purchase approval authority. Depending on the value of the purchase, this authority may approve the request or forward it to the next authority in the chain.
For example let’s say a request is placed for the purchase of a new keyboard for an office. The value of the purchase is not that big, so the request is sent from the head of the office to the head of the department and then to the materials department where it stops, being handled locally. But if equipment for the whole department is needed then the request goes form the head of the department, to materials department, to the purchase office and even to the manager if the value is too big.
Example 2
In designing the software that uses a set of GUI classes where it is needed to propagate GUI events from one object to another.
When an event, such as the pressing of a key or the click of the mouse, the event is needed to be sent to the object that has generated it and also to the object or objects that will handle it.
The Client is, of course, the object that has generated the event, the request is the event and the handlers are the objects that can handle it. So, if we have a handler for the click of the mouse, a handler for the pressing of the ‘Enter’ key and a handler for the pressing of the ‘Delete’ key, that is the chain of handlers that take care of the events that are generated.
Example 3
In designing a shipping system for electronic orders.
The steps to complete and handle the order differs form one order to another based on the customer, the size of the order, the way of shipment, destination and more other reasons. The business logic changes also as special cases appear, needing the system to be able to handle all cases.
The Client, the electronic order in process, requests shipping based on a set of pieces of information. Its request is turned by the system into a specific form, combining the steps to completing and the details of handling, based on the input information. The system will send this type of request through a chain of order-handlers until the input information that it comes with matches the input the order-handles takes. When special cases appear, all that is needed is a new handler to be added in the chain.
The object that ultimately handles the request is unknown explicitly to the sender object that sends the request. By this way we are using chain of responsibility pattern to decouple the sender of the request and its receivers.
Each object on the chain shares a common interface for handling requests and for accessing its successor on the chain.
Receipt is not guaranteed - a request could fall off the end of the chain without being handled.
The Java Servlet filter framework is an example of chain of resposibility design. Note that the chain.doFilter() is the method that should be called to make the chain roll. If the subclass missed it, the whole chain would be stopped or blocked.
Java exception handling is another example of chain of responsibility design. When an error occurs, the exception call will look for a handling class. If there is no handler, the super Exception class will be called to throw the exception. Otherwise, the handler class will handle it. Processing stops after an event is handled.
Chain of responsibility simplifies object interconnections.Instead of senders and receivers maintaining references to all candidate receivers,each sender keeps a single reference to the head of the chain,and each receiver keeps a single reference to the immediate successor in the chain.
Chain Of Responsibility uses Command Pattern to represent requests as objects.
Chain of Responsibility is often applied in conjunction with CompositePattern.There,a component's parent act as its successor.
abstract class Car {
public double price = 5.5;
public String color = "Silver";
public String size = "Small";
// The Next Element in the Chain of Responsibility
protected Car next;
protected Car searchNext(Car car) {
next=car;
return this;
}
public void trail(String performance) {
if(price < 10 && performance.equalsIgnoreCase("Satisfactory")){
buyCar(performance);
}
else{
if(next!=null)
next.trail(performance);
}
}
abstract protected void buyCar(String performance);
}
public class Innova extends Car{
public Innova(double price,String color,String size) {
this.price = price;
this.color = color;
this.size = size;
}
protected void buyCar(String performance) {
System.out.println("Liked Innova ... performance... "+performance);
}
}
public class Toyota extends Car{
public Toyota(double price,String color,String size) {
this.price = price;
this.color = color;
this.size = size;
}
protected void buyCar(String performance) {
System.out.println(" Liked Toyota ... performance... "+performance);
}
}
public class SearchCars {
public static void main(String[] args) {
Car car=new Toyota(10.5,"black","big").searchNext(new Innova(8.5,"silver","medium"));
car.trail("Satisfactory");
}
}
When To Use:
1. Use Chain Of Responsibility Pattern when you want to give more than one object a chance to handle a request and the actual handler is not known in advance.
2. Commonly used in windows systems to handle events like mouse clicks and keyboard events.
3. When you want to avoid coupling the sender of a request to its receiver.
Advantages:
1. Decouples the sender of the request and its receivers.
2. Simplifies your object as it doesn't have to know about the chain structure and keep direct references to its members.
3. Allows you to add or remove responsibilities dynamically by changing the members or order of the chain.
Example 1
In designing the software for a system that approves the purchasing requests.
In this case, the values of purchase are divided into categories, each having its own approval authority. The approval authority for a given value could change at any time and the system should be flexible enough to handle the situation.
The Client in the example above is the system in need of the answer to the approval. It sends a request about it to an purchase approval authority. Depending on the value of the purchase, this authority may approve the request or forward it to the next authority in the chain.
For example let’s say a request is placed for the purchase of a new keyboard for an office. The value of the purchase is not that big, so the request is sent from the head of the office to the head of the department and then to the materials department where it stops, being handled locally. But if equipment for the whole department is needed then the request goes form the head of the department, to materials department, to the purchase office and even to the manager if the value is too big.
Example 2
In designing the software that uses a set of GUI classes where it is needed to propagate GUI events from one object to another.
When an event, such as the pressing of a key or the click of the mouse, the event is needed to be sent to the object that has generated it and also to the object or objects that will handle it.
The Client is, of course, the object that has generated the event, the request is the event and the handlers are the objects that can handle it. So, if we have a handler for the click of the mouse, a handler for the pressing of the ‘Enter’ key and a handler for the pressing of the ‘Delete’ key, that is the chain of handlers that take care of the events that are generated.
Example 3
In designing a shipping system for electronic orders.
The steps to complete and handle the order differs form one order to another based on the customer, the size of the order, the way of shipment, destination and more other reasons. The business logic changes also as special cases appear, needing the system to be able to handle all cases.
The Client, the electronic order in process, requests shipping based on a set of pieces of information. Its request is turned by the system into a specific form, combining the steps to completing and the details of handling, based on the input information. The system will send this type of request through a chain of order-handlers until the input information that it comes with matches the input the order-handles takes. When special cases appear, all that is needed is a new handler to be added in the chain.