In this post, We will talk and learn about the Chain of Responsibility Design Pattern in Java
Key Points About Chain of Responsibility Design Pattern :
- The chain of responsibility design pattern falls under behavioral design pattern.
- The chain of responsibility design pattern is mainly used to gain loose coupling in software design where a request from the client is passed to a chain of objects to process the request. Then the object in the chain has to decide who will be processing the request and whether the request is required to be sent to the next object in the chain or not.
- The client does not know which Object in the chain will be processing the request and it will send the request to the first object in the chain.
- Every object in the chain will have its own implementation to process the request, either complete or partial, or to send it to the next object in the chain.
- Every object in the chain should have reference to the next object in the chain to forward the request to, it is achieved by java composition.
- We should be careful while creating the chain otherwise there might be a case that the request will never be forwarded to a particular processor or there are no objects in the chain that are able to handle the request.
Chain of Responsibility Pattern in JDK:
Now Let’s move towards the implementation of the Chain of ResponsibilityDesign Pattern.
Here I am going to implement blow Use Case :
- One of the great examples of the Chain of Responsibility pattern is the ATM machine.
- The user enters the amount to be dispensed and the machine dispense amount in terms of defined currency Notes such as Rs 2000, Rs 500, Rs 200 and Rs 100
Below is the complete source code:
MoneyDispenseChain.java
1 2 3 4 5 6 7 8 9 10 11 12 13 |
package com.kkjavatutorials.chain; import com.kkjavatutorials.currency.Currency; /** * @author KK JavaTutorials * Contract to process request in chain and * dispense */ public interface MoneyDispenseChain { public abstract void setNextChain(MoneyDispenseChain moneyDispenseChain); public abstract void dispense(Currency currency); } |
Currency.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
package com.kkjavatutorials.currency; /** * @author KK JavaTutorials * Model class represent amount */ public class Currency { private int amount; public Currency(int amount) { this.amount = amount; } public int getAmount() { return amount; } } |
Rupees100DispenseChain.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
package com.kkjavatutorials.chain.impl; import com.kkjavatutorials.chain.MoneyDispenseChain; import com.kkjavatutorials.currency.Currency; /** * @author KK JavaTutorials * Filter in the chain responsible to process Rs 100 note */ public class Rupees100DispenseChain implements MoneyDispenseChain { private MoneyDispenseChain moneyDispenseChain; @Override public void setNextChain(MoneyDispenseChain moneyDispenseChain) { this.moneyDispenseChain = moneyDispenseChain; } @Override public void dispense(Currency currency) { if(currency.getAmount() >=100) { int numberOfNotes = currency.getAmount()/100; int remainder = currency.getAmount() % 100; System.out.println("Depensing " + numberOfNotes +" Notes of Rs 100"); if(remainder !=0) { moneyDispenseChain.dispense(new Currency(remainder)); } }else { moneyDispenseChain.dispense(currency); } } } |
Rupees200DispenseChain.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
package com.kkjavatutorials.chain.impl; import com.kkjavatutorials.chain.MoneyDispenseChain; import com.kkjavatutorials.currency.Currency; /** * @author KK JavaTutorials *Filter in the chain responsible to process Rs 200 note */ public class Rupees200DispenseChain implements MoneyDispenseChain { private MoneyDispenseChain moneyDispenseChain; @Override public void setNextChain(MoneyDispenseChain moneyDispenseChain) { this.moneyDispenseChain = moneyDispenseChain; } @Override public void dispense(Currency currency) { if(currency.getAmount() >=200) { int numberOfNotes = currency.getAmount()/200; int remainder = currency.getAmount() % 200; System.out.println("Depensing " + numberOfNotes +" Notes of Rs 200"); if(remainder !=0) { moneyDispenseChain.dispense(new Currency(remainder)); } }else { moneyDispenseChain.dispense(currency); } } } |
Rupees500DispenseChain.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
package com.kkjavatutorials.chain.impl; import com.kkjavatutorials.chain.MoneyDispenseChain; import com.kkjavatutorials.currency.Currency; /** * @author KK JavaTutorials *Filter in the chain responsible to process Rs 500 note */ public class Rupees500DispenseChain implements MoneyDispenseChain { private MoneyDispenseChain moneyDispenseChain; @Override public void setNextChain(MoneyDispenseChain moneyDispenseChain) { this.moneyDispenseChain = moneyDispenseChain; } @Override public void dispense(Currency currency) { if(currency.getAmount() >=500) { int numberOfNotes = currency.getAmount()/500; int remainder = currency.getAmount() % 500; System.out.println("Depensing " + numberOfNotes +" Notes of Rs 500"); if(remainder !=0) { moneyDispenseChain.dispense(new Currency(remainder)); } }else { moneyDispenseChain.dispense(currency); } } } |
Rupees2000DispenseChain.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
package com.kkjavatutorials.chain.impl; import com.kkjavatutorials.chain.MoneyDispenseChain; import com.kkjavatutorials.currency.Currency; /** * @author KK JavaTutorials *Filter in the chain responsible to process Rs 2000 note */ public class Rupees2000DispenseChain implements MoneyDispenseChain { private MoneyDispenseChain moneyDispenseChain; @Override public void setNextChain(MoneyDispenseChain moneyDispenseChain) { this.moneyDispenseChain = moneyDispenseChain; } @Override public void dispense(Currency currency) { if(currency.getAmount() >=2000) { int numberOfNotes = currency.getAmount()/2000; int remainder = currency.getAmount() % 2000; System.out.println("Depensing " + numberOfNotes +" Notes of Rs 2000"); if(remainder !=0) { moneyDispenseChain.dispense(new Currency(remainder)); } }else { moneyDispenseChain.dispense(currency); } } } |
ATMMachineDispenseChain.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
package com.kkjavatutorials.chain.impl; import com.kkjavatutorials.chain.MoneyDispenseChain; /** * @author KK JavaTutorials *Every object in the chain will have to process the request, *either complete or partial,or to send it to the next object in the chain. */ public class ATMMachineDispenseChain { private MoneyDispenseChain moneyDispenseChain1; public ATMMachineDispenseChain() { moneyDispenseChain1 = new Rupees2000DispenseChain(); MoneyDispenseChain moneyDispenseChain2 = new Rupees500DispenseChain(); MoneyDispenseChain moneyDispenseChain3 = new Rupees200DispenseChain(); MoneyDispenseChain moneyDispenseChain4 = new Rupees100DispenseChain(); moneyDispenseChain1.setNextChain(moneyDispenseChain2); moneyDispenseChain2.setNextChain(moneyDispenseChain3); moneyDispenseChain3.setNextChain(moneyDispenseChain4); } public MoneyDispenseChain getMoneyDispenseChain1() { return moneyDispenseChain1; } } |
ClientTest.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
package com.kkjavatutorials.client; import java.util.Scanner; import com.kkjavatutorials.chain.impl.ATMMachineDispenseChain; import com.kkjavatutorials.currency.Currency; /** * @author KK JavaTutorials * Client Program which accepts amount for processing * if Entered amount is not multiple of Rs 100 * Than it will print message * "Amount should be multiple of Rs 100" * and end the process */ public class ClientTest { @SuppressWarnings("resource") public static void main(String[] args) { ATMMachineDispenseChain atmMachineDispenseChain = new ATMMachineDispenseChain(); Scanner scanner = null; while (true) { int amout = 0; try { System.out.println("Please enter amout to despense:"); scanner = new Scanner(System.in); amout= scanner.nextInt(); if(amout %100 !=0) { System.out.println("Amount should be multiple of Rs 100"); return; }else { atmMachineDispenseChain.getMoneyDispenseChain1().dispense(new Currency(amout)); } } catch (Exception e) { e.printStackTrace(); } } } } |
Few Input & Output of this client Program:
Please enter amout to despense:
15200
Depensing 7 Notes of Rs 2000
Depensing 2 Notes of Rs 500
Depensing 1 Notes of Rs 200
Please enter amout to despense:
6700
Depensing 3 Notes of Rs 2000
Depensing 1 Notes of Rs 500
Depensing 1 Notes of Rs 200
Please enter amout to despense:
450
Amount should be multiple of Rs 100
You May Also Like:
Singleton Design Pattern in java
Prototype Pattern in Java
Factory Pattern in Java
Abstract Factory Pattern in Java
Builder Pattern in Java
Adapter Design Pattern in Java
Decorator Design Pattern in Java
Facade Design Pattern in Java
Bridge Design Pattern in Java.
That’s all about the Chain of Responsibility Design Pattern in Java.
If you have any feedback or suggestion please feel free to drop in below comment box.