Chain of Responsibility

Definition


Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.

UML class diagram


Participants


  • Handler
    • defines an interface for handling the requests
    • (optional) implements the successor link
  • ConcreteHandler
    • handles requests it is responsible for
    • can access its successor
    • if the ConcreteHandler can handle the request, it does so; otherwise it forwards the request to its successor
  • Client
    • initiates the request to a ConcreteHandler object on the chain

Sample code in Java

package com.hong.chainOfResp;

abstract class Handler {
    protected Handler handler; 
    public void setHandler(Handler handler){
        this.handler = handler;
    }
    public abstract void handleRequest(int number);
}

class ConcreteHandler1 extends Handler{

    @Override
    public void handleRequest(int number) {
    
        if(number < 0)  {
            System.out.printf("%d is handled by Handler1
", number);
        }
        else{
            handler.handleRequest(number);
        }
    }
}

class ConcreteHandler2 extends Handler{

    @Override
    public void handleRequest(int number) {
        if( number >= 0 && number < 100 ){
            System.out.printf("%d is handled by Handler2
", number);
        }
        else {
            handler.handleRequest(number);
        }   
    }
}

class ConcreteHandler3 extends Handler{

    @Override
    public void handleRequest(int number){
        
        if(number > 100) {
            System.out.printf("%d is handled by Handler3
", number);
        }
    }
}

public class ChainOfResp_structure {
    
        public static void main(String[] args) {
        
        int[] numbers = {2, -1, -23, 9, 115, 27, 255 }; 
        Handler handler1 = new ConcreteHandler1();
        Handler handler2 = new ConcreteHandler2();
        Handler handler3 = new ConcreteHandler3();
        
        handler1.setHandler(handler2);
        handler2.setHandler(handler3);

        for(int number : numbers)
        {
            handler1.handleRequest(number);
        }
        
    }
}