Thursday, July 25, 2019

Chain Of Responsibility Design Pattern

Let's start "Chain of Responsibility design pattern".This is one of behavioral patterns in Gang Of four Design Pattern.
The definition of Chain of Responsibility pattern provided by Gang of Four book on Design Patterns states:
"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."

By using Chain of Responsibility design pattern. I am taking an example of currency.
Suppose i want to know,the number of currency(INR of  2000,500,200,100) will be return by ATM if All currency will be there.
Currency.java

package com.shubh.currency;

import com.shubh.currency.model.ATM;

public interface Currency {
 public void process(ATM atm);
 public void setNextCurrency(Currency nextCurrency);
}

Currency2000.java

package com.shubh.currency.impl;

import java.util.Map;
import com.shubh.currency.Currency;
import com.shubh.currency.model.ATM;

public class Currency2000 implements Currency {

 private int netAmount;
 private int withdraw;
 private int balance;
 private int numberOfCurrency;
 private int currencyValue = 2000;
 private Currency nextCurrency;

 public void process(ATM atm) {
  netAmount = atm.getAmount();
  balance = atm.getBalance();
  if (balance != 0 && netAmount > balance) {
   netAmount = balance;
  }
  if (netAmount >= currencyValue) {
   withdraw = netAmount - netAmount % currencyValue;
   numberOfCurrency = withdraw / currencyValue;
   balance = netAmount - withdraw;
   System.out.println("Currency: " + currencyValue + ": "
     + numberOfCurrency + ", Balance: " + balance);
   Map currencyDetails = atm.getCurrencyDetails();
   currencyDetails.put(currencyValue + "", numberOfCurrency);
   atm.setBalance(balance);
   atm.setCurrencyDetails(currencyDetails);
  }
  if (atm.getBalance() > 0) {
   nextCurrency.process(atm);
  }

 }

 public void setNextCurrency(Currency nextCurrency) {
  this.nextCurrency = nextCurrency;
 }
}
Currency500.java

package com.shubh.currency.impl;

import java.util.Map;

import com.shubh.currency.Currency;
import com.shubh.currency.model.ATM;

public class Currency500 implements Currency {

 private int netAmount;
 private int withdraw;
 private int balance;
 private int numberOfCurrency;
 private int currencyValue = 500;
 private Currency nextCurrency;

 public void process(ATM atm) {
  netAmount = atm.getAmount();
  balance = atm.getBalance();
  if (balance != 0 && netAmount > balance) {
   netAmount = balance;
  }
  if (netAmount >= currencyValue) {
   withdraw = netAmount - netAmount % currencyValue;
   numberOfCurrency = withdraw / currencyValue;
   balance = netAmount - withdraw;
   System.out.println("Currency: " + currencyValue + ": "
     + numberOfCurrency + ", Balance: " + balance);
   Map currencyDetails = atm.getCurrencyDetails();
   currencyDetails.put(currencyValue + "", numberOfCurrency);
   atm.setBalance(balance);
   atm.setCurrencyDetails(currencyDetails);
  }
  if (atm.getBalance() > 0) {
   nextCurrency.process(atm);
  }

 }

 public void setNextCurrency(Currency nextCurrency) {
  this.nextCurrency = nextCurrency;
 }
}
Currency200.java

package com.shubh.currency.impl;

import java.util.Map;
import com.shubh.currency.Currency;
import com.shubh.currency.model.ATM;

public class Currency200 implements Currency {

 private int netAmount;
 private int withdraw;
 private int balance;
 private int numberOfCurrency;
 private int currencyValue = 200;
 private Currency nextCurrency;

 public void process(ATM atm) {
  netAmount = atm.getAmount();
  balance = atm.getBalance();
  if (balance != 0 && netAmount > balance) {
   netAmount = balance;
  }
  if (netAmount >= currencyValue) {
   withdraw = netAmount - netAmount % currencyValue;
   numberOfCurrency = withdraw / currencyValue;
   balance = netAmount - withdraw;
   System.out.println("Currency: " + currencyValue + ": "
     + numberOfCurrency + ", Balance: " + balance);
   Map currencyDetails = atm.getCurrencyDetails();
   currencyDetails.put(currencyValue + "", numberOfCurrency);
   atm.setBalance(balance);
   atm.setCurrencyDetails(currencyDetails);
  }
  if (atm.getBalance() > 0) {
   nextCurrency.process(atm);
  }
 }

 public void setNextCurrency(Currency nextCurrency) {
  this.nextCurrency = nextCurrency;
 }
}
Currency100.java

package com.shubh.currency.impl;

import java.util.Map;
import com.shubh.currency.Currency;
import com.shubh.currency.model.ATM;

public class Currency100 implements Currency {

 private int netAmount;
 private int withdraw;
 private int balance;
 private int numberOfCurrency;
 private int currencyValue = 100;
 private Currency nextCurrency;

 public void process(ATM atm) {
  netAmount = atm.getAmount();
  balance = atm.getBalance();
  if (balance != 0 && netAmount > balance) {
   netAmount = balance;
  }
  if (netAmount >= currencyValue) {
   withdraw = netAmount - netAmount % currencyValue;
   numberOfCurrency = withdraw / currencyValue;
   balance = netAmount - withdraw;
   System.out.println("Currency: " + currencyValue + ": "
     + numberOfCurrency + ", Balance: " + balance);
   Map currencyDetails = atm.getCurrencyDetails();
   currencyDetails.put(currencyValue + "", numberOfCurrency);
   atm.setBalance(balance);
   atm.setCurrencyDetails(currencyDetails);
  }
  if (atm.getBalance() > 0) {
   // as we are not using currency less then 100 so no need for this.
   // nextCurrency.process(atm);
  }

 }

 public void setNextCurrency(Currency nextCurrency) {
  this.nextCurrency = nextCurrency;
 }
}
Let's Test:- CurrencyApplication.java

package com.shubh.application;

import com.shubh.currency.Currency;
import com.shubh.currency.impl.Currency100;
import com.shubh.currency.impl.Currency200;
import com.shubh.currency.impl.Currency2000;
import com.shubh.currency.impl.Currency500;
import com.shubh.currency.model.ATM;

public class CurrencyApplication {
 public static void main(String[] args) {

  System.out.println("Start Main.");
  Currency currency2000 = new Currency2000();
  Currency currency500 = new Currency500();
  Currency currency200 = new Currency200();
  Currency currency100 = new Currency100();

  // Set next object to process chain of objects
  currency2000.setNextCurrency(currency500);
  currency500.setNextCurrency(currency200);
  currency200.setNextCurrency(currency100);

  ATM atm = new ATM();
  atm.setAmount(2800);

  currency2000.process(atm);
  System.out.println(atm);
  System.out.println("End Main.");
 }
}
Outpot:-

Start Main.
Currency: 2000: 1, Balance: 800
Currency: 500: 1, Balance: 300
Currency: 200: 1, Balance: 100
Currency: 100: 1, Balance: 0
{100=1, 200=1, 500=1, 2000=1}
End Main.
As you can see in the output.
Input amount is Rs 2800/-. First request as been processed by the Currency2000. So Since we can't get more than one currency of Rs.2000/- So it will give one currency of 2000 and  the balance amount is Rs 800/-. Now request has been sent to Currency500 for balance amount Rs 800/- so on.

No comments:

Post a Comment