Tuesday, December 2, 2014

Chain of Responsibility Design Pattern


Design Pattern > Behavioral Design Pattern > Chain of Responsibility Design Pattern

Chain of responsibility helps to decouple sender of a request and receiver of the request with some trade-offs. Chain of responsibility is a design pattern where a sender sends a request to a chain of objects, where the objects in the chain decide themselves who to honor the request. If an object in the chain decides not to serve the request, it forwards the request to the next object in the chain.

Responsibility is outsourced. In a chain of objects, the responsibility of deciding who to serve the request is left to the objects participating in the chains.
The most usual example of a machine using the Chain of Responsibility is the vending machine coin slot: rather than having a slot for each type of coin, the machine has only one slot for all of them. The dropped coin is routed to the appropriate storage place that is determined by the receiver of the command.

Having so many design patterns to choose from when writing an application, it's hard to decide on which one to use, so here are a few situations when using the Chain of Responsibility is more effective:

  • More than one object can handle a command
  • The handler is not known in advance
  • The handler should be determined automatically
  • It’s wished that the request is addressed to a group of objects without explicitly specifying its receiver
  • The group of objects that may handle the command must be specified in a dynamic way

Example Java Code

Digit.java

package com.kmingle.chainofresponsibility;

public class Digit {

private int digit;
public Digit(int digit){
this.digit = digit;
}

public int getDigit() {
return digit;
}
}

Handler.java

package com.kmingle.chainofresponsibility;

public interface Handler {

public abstract void setNextHandler(Handler nextHandler);
public abstract void processRequest(Digit input);
}


NegativeHandler.java

package com.kmingle.chainofresponsibility;

public class NegativeHandler implements Handler{

private Handler nextHandler;

@Override
public void setNextHandler(Handler nxtHandler) {

nextHandler = nxtHandler;
}

@Override
public void processRequest(Digit input) {

if(input.getDigit() < 0){
System.out.println("handled by negative handler : "+ input.getDigit());
}
else {
nextHandler.processRequest(input);
}
}

}

PositiveHandler.java 

package com.kmingle.chainofresponsibility;

public class PositiveHandler implements Handler{

private Handler nextHandler;
@Override
public void setNextHandler(Handler nxtHandler) {
nextHandler = nxtHandler;
}

@Override
public void processRequest(Digit input) {
if(input.getDigit() > 0){
System.out.println("handled by positive handler : "+ input.getDigit());
}
else {
nextHandler.processRequest(input);
}
}

}

ZeroHandler.java 

package com.kmingle.chainofresponsibility;

public class ZeroHandler implements Handler{

private Handler nextHandler;
@Override
public void setNextHandler(Handler nxtHandler) {
nextHandler = nxtHandler;
}

@Override
public void processRequest(Digit input) {
if(input.getDigit() == 0){
System.out.println("handled by zero handler : "+ input.getDigit());
}
else {
nextHandler.processRequest(input);
}
}

}

Requester.java

package com.kmingle.chainofresponsibility;

public class Requester {
public static void main(String[] args) {
// configuration for request handler chains
Handler h1 = new Negativehandler();
Handler h2 = new Positivehandler();
Handler h3 = new Zerohandler();
h1.setNextHandler(h2);
h2.setNextHandler(h3);
// calling chain
h1.processRequest(new Digit(10));
h1.processRequest(new Digit(-10));
h1.processRequest(new Digit(0));
h1.processRequest(new Digit(20));
}

}

Output :

handled by positive handler : 10
handled by negative handler : -10
handled by zero handler : 0
handled by positive handler : 20

No comments:

Total Pageviews