Problem

The number of handlers (nodes) and number of processes can vary. We need to process requests without hard-coding a precedence relationship mapping.

Solution

Avoid coupling the sender of a request with the recipient. Chain the receiving objects and pass the request along until it is marked done somehwhere down the line.

Related Patterns

Discussion

Chain of Responsibility simplifies object interactions. The recursive chain allows an arbitrary number of links to be added without prior knowledge of it. Essentially a linked list for processing requests.

Examples

A real-world example of the Chain of Responsibility pattern is a cash distribution module inside an ATM: The desired amount is passed to the tray for the largest bill denomination where bills are dispensed until the next bill would exceed that amount. The request is passed on to the next smallest denomination until the desired amount is met.

Code

This Java sample demonstrates the abstraction of the Chain of Responsibility. The task gets passed to the appropriate Processor (where a pseudo-random int determines the busy state, for demonstration purposes). When the Processor is not "busy", it process()es the proper Image.

interface Image{
  String process();
}

static class Sepia implements Image{
  public String process(){return "Sepia";}
}
static class BW implements Image{
  public String process(){return "B/W";}
}

static class Processor{
  private static java.util.Random rand = new java.util.Random();
  private static int nextId = 1;
  private int id = nextId++;
  public boolean handle(Image img){
    if(rand.nextInt(2) != 0){
      System.out.println("Processor " + id + " is busy.");
      return false;
    }
    System.out.println("Processor " + id + ": " + img.process());
    return true;
  }
}

public static void main(String[] args){
  Image[] imgs = {new Sepia(), new BW(), new BW(), new Sepia(), new BW()};
  Processor[] processors = {new Processor(), new Processor(), new Processor()};
  for(int i = 0, j; i < input.length; i++){
    j = 0;
    while(!procs[j].handle(imgs[i])) j = (j+1) % processors.length;
  }
}