Friday 6 February 2015

Chain of Responsibility Implementation

Chain of Responsibility Design Pattern

Hibernate                                                                                              Core Java


Question :- What is Chain of Responsibility Design Pattern?
Answer : - 


As per GOF : -"Gives more than one object an opportunity to handle a request by linking receiving objects together."

Question: - When to use Chain of Responsibility design pattern?

1. This design pattern helps to reduced coupling between the sender of a request and the receiver – the sender and receiver are not aware about each other means sender will not know which object in the chain will serve its request. In a chain of objects, the responsibility of deciding who to serve the request is left to the objects participating in the chains.

2. When more than one object may handle a request and the actual handler object is not know in advance or when requests follow a model - that is, some requests can be handled where they are generated while others must be forwarded to another object to be handled.

3. Dynamically, the chain of handlers can be modified.

Disadvantage : -
There is a possibility that a request could fall off the end of the chain without being handled.

Examples in JAVA API :

In JDK, we know about try-catch block, where we can mention multiple catch blocks. When exception occurs in try block then every catch block which are a kind of processor tries to process that exception, if catch clock is not able to handle that exception then it is forwarding to next catch block in chainalize manner. If last catch block is also not able to handle the occurred exception then the exception is thrown outside of the chain to the calling program.

javax.servlet.Filter -> doFilter()
The doFilter method of the Filter class is called by the container each time when a request or response is passed through the chain. The FilterChain object passed in to this method allows the Filter to pass on the request and response to the next entity in the chain for serving the request and providing the response to the intended recipient.

In Live example, we can think about the customer support of any organization which is based on chaining system or the hierarchy of a purchase department for approval of payment amount based on designation. 

Below we will implement the purchase department hierarchy example using chain of responsibility design pattern. In this example we will see that how request is processing in the chain and after process how we will get response after filtration.

AuthTypeRequest .java
package com.gaurav.designpattern.chainofresponsibility;

public class AuthTypeRequest {

private double amount;
private String expenditureType;

public AuthTypeRequest(String expenditure, double amount) {
this.expenditureType = expenditure;
this.amount = amount;
}

public double getAmount() {
return amount;
}

public void setAmount(double amt) {
amount = amt;
}

public String getExpenditureType() {
return expenditureType;
}

public void setExpenditureType(String expenditureType) {
this.expenditureType = expenditureType;
}

}

AuthorizationCapacity.java

package com.gaurav.designpattern.chainofresponsibility;

abstract class AuthorizationCapacity {

    protected final double limit = 50000;
    protected AuthorizationCapacity authCapacity;

    public void setOrganizationalHierarchy(AuthorizationCapacity authorizationCapacity){
        this.authCapacity = authorizationCapacity;
    }

    abstract public void serveRequest(AuthTypeRequest request);

}


HRManager.java

package com.gaurav.designpattern.chainofresponsibility;

public class HRManager extends AuthorizationCapacity {
    private final double EXPENDITURE_LIMIT = 10 * limit;

    public void serveRequest(AuthTypeRequest authTypeRequest ) {
        if( authTypeRequest.getAmount() < EXPENDITURE_LIMIT ){
            System.out.println("HR MANAGER EXPENDITURE LIMIT FOR APPROVAL IS : "+EXPENDITURE_LIMIT);
            System.out.println("AS SPENT AMOUNT "+authTypeRequest.getAmount()+" FALLS UNDER HIS EXPENDITURE LIMIT,SO HE CAN APPROVE THIS.");
        }
        else
           if( authCapacity != null)
          authCapacity.serveRequest(authTypeRequest);
  }
}

Director.java

package com.gaurav.designpattern.chainofresponsibility;

public class Director extends AuthorizationCapacity {
    private final double EXPENDITURE_LIMIT = 30 * limit;

    public void serveRequest(AuthTypeRequest authTypeRequest ) {
        if( authTypeRequest.getAmount() < EXPENDITURE_LIMIT ){
        System.out.println("DIRECTOR EXPENDITURE LIMIT FOR APPROVAL IS : "+EXPENDITURE_LIMIT);
       
        System.out.println("AS SPENT AMOUNT "+authTypeRequest.getAmount()+" FALLS UNDER HIS EXPENDITURE LIMIT,SO HE CAN APPROVE THIS.");
            }
        else
           if( authCapacity != null)
          authCapacity.serveRequest(authTypeRequest);
  }
}

VicePresident.java

package com.gaurav.designpattern.chainofresponsibility;

public class VicePresident extends AuthorizationCapacity {
    private final double EXPENDITURE_LIMIT = 50 * limit;

    public void serveRequest(AuthTypeRequest authTypeRequest ) {
        if( authTypeRequest.getAmount() < EXPENDITURE_LIMIT ){
       
        System.out.println("DIRECTOR EXPENDITURE LIMIT FOR APPROVAL IS : "+EXPENDITURE_LIMIT);
       
        System.out.println("AS SPENT AMOUNT "+authTypeRequest.getAmount()+" FALLS UNDER HIS EXPENDITURE LIMIT, SO HE CAN APPROVE THIS.");
        }
        else
           if( authCapacity != null)
          authCapacity.serveRequest(authTypeRequest);
  }
}

CEO.java

package com.gaurav.designpattern.chainofresponsibility;

public class CEO extends AuthorizationCapacity {
    private final double EXPENDITURE_LIMIT = 70 * limit;

    public void serveRequest(AuthTypeRequest authTypeRequest ) {
    if(authTypeRequest.getAmount()> EXPENDITURE_LIMIT)
    {
    System.out.println("AS PER POLICY THE EXPENDITURE LIMIT OF CEO IS : "+EXPENDITURE_LIMIT);
    System.out.println("AS SPENT AMOUNT "+authTypeRequest.getAmount()+" IS ABOUVE EXPENDITURE LIMIT OF CEO. SO HE NEEDS SHAREHOLDERS APPROVAL TO APPROVE THIS AMOUNT.");
    }
    if( authTypeRequest.getAmount() < EXPENDITURE_LIMIT ){
            System.out.println("A CEO IS THE OWNER OF THE COMPANY, \nSO HE IS HAVING POWER TO APPROVE COMPLETE AMOUNT \nBUT HE ALSO NEED TO TAKE OPINION FROM OTHER DIRECTORS SO THE APPROVAL AMOUNT IS i.e. INR : "+ EXPENDITURE_LIMIT);
            System.out.println("AS SPENT AMOUNT FALLS UNDER HIS EXPENDITURE LIMIT,SO HE CAN APPROVE THIS.");
        }
        else
           if( authCapacity != null)
          authCapacity.serveRequest(authTypeRequest);
  }
}

ChainofResponsibilityDesignPatternDemo.java

package com.gaurav.designpattern.chainofresponsibility;

import java.util.Scanner;

public class ChainofResponsibilityDesignPatternDemo {
private static Scanner enteredVal;

public static void main(String[] args) throws Exception{
HRManager hrmanager = new HRManager();
       Director director = new Director();
       VicePresident vp = new VicePresident();
       CEO ceo = new CEO();
      
       hrmanager.setOrganizationalHierarchy(director);
       director.setOrganizationalHierarchy(vp);
       vp.setOrganizationalHierarchy(ceo);
       
       enteredVal = new Scanner(System.in);
       
       System.out.println("Enter the expenditure type : ");
       String expenditureType = enteredVal.nextLine(); 
       
       System.out.println("Enter the amount spent for the work : ");
       double amount = enteredVal.nextDouble();
       
           System.out.println("Check inside the organization who is having limit to approve for expenditure : ");
           AuthTypeRequest authTypeRequest = new AuthTypeRequest(expenditureType, amount);
           hrmanager.serveRequest(authTypeRequest);

 }
}


Result:

Scenario 1 :

Enter the expenditure type : 
Stationary
Enter the amount spent for the work : 
50000
Check inside the organization who is having limit to approve for expenditure : 
HR MANAGER EXPENDITURE LIMIT FOR APPROVAL IS : 500000.0
AS SPENT AMOUNT 50000.0 FALLS UNDER HIS EXPENDITURE LIMIT,SO HE CAN APPROVE THIS.

Scenario 2 :

Enter the expenditure type : 
Resource Hiring
Enter the amount spent for the work : 
1000000
Check inside the organization who is having limit to approve for expenditure : 
DIRECTOR EXPENDITURE LIMIT FOR APPROVAL IS : 1500000.0
AS SPENT AMOUNT 1000000.0 FALLS UNDER HIS EXPENDITURE LIMIT,SO HE CAN APPROVE THIS.

Scenario 3 :

Enter the expenditure type : 
Campus renovation
Enter the amount spent for the work : 
2000000
Check inside the organization who is having limit to approve for expenditure : 
VICE PRESIDENT EXPENDITURE LIMIT FOR APPROVAL IS : 2500000.0
AS SPENT AMOUNT 2000000.0 FALLS UNDER HIS EXPENDITURE LIMIT, SO HE CAN APPROVE THIS.

Scenario 4 :

Enter the expenditure type : 
Company Extension
Enter the amount spent for the work : 
3000000
Check inside the organization who is having limit to approve for expenditure : 
A CEO IS THE OWNER OF THE COMPANY, 
SO HE IS HAVING POWER TO APPROVE COMPLETE AMOUNT 
BUT HE ALSO NEED TO TAKE OPINION FROM OTHER DIRECTORS SO THE APPROVAL AMOUNT IS i.e. INR : 3500000.0
AS SPENT AMOUNT FALLS UNDER HIS EXPENDITURE LIMIT,SO HE CAN APPROVE THIS.

Scenario 5 :

Enter the expenditure type : 
Share Listing
Enter the amount spent for the work : 
4000000
Check inside the organization who is having limit to approve for expenditure : 
AS PER POLICY THE EXPENDITURE LIMIT OF CEO IS : 3500000.0
AS SPENT AMOUNT 4000000.0 IS ABOUVE EXPENDITURE LIMIT OF CEO. SO HE NEEDS SHAREHOLDERS APPROVAL TO APPROVE THIS AMOUNT.


No comments:

Post a Comment