Chain of responsibility is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain. A mechanism also exists for adding new processing objects to the end of this chain.
In simple way, chain of responsibility pattern creates a chain of receiver object for a request. This pattern decouple sender and receiver of request based on type of object. This pattern comes under behavioral design pattern.
Lets, understand this pattern with real world scenario.
In corporate office, company provide some facility to their employees to claim expenses on particular usages like internet, corporate travel etc. Employee pays bill for these expenses themselves, after that employee reimburse expense from company. When Employee claims the expense, these expense request goes to their manager for approval, if this claim amount limit comes under manager's approval limit then he/she will approve it, otherwise request will be transferred to his/her manager. If it is not also his/her limits then it will passed to the next higher level manager.
Implementation
We have different roles, each having a fixed purchasing limit and a successor. Every time a user in a role receives a purchase request that exceeds his or her limit, the request is passed to his or her successor. We are going to create PurchasePower abstract class with abstract method processRequest and concrete classes extending this abstract class. We will have created PurchaseRequest class that keeps purchase data.
UML:
Step 1
Create an abstract class PurchasePower.
public abstract class PurchasePower { protected PurchasePower successor; protected static final double BASE = 500; abstract protected double getAllowable(); abstract protected String getRole(); public void setSuccessor(PurchasePower successor) { this.successor = successor; } public void processRequest(PurchaseRequest request) { if (request.getAmount() < getAllowable()) { System.out.println(getRole() + " will approve $" + request.getAmount()); } else if (successor != null) { successor.processRequest(request); } } }
Step 2
Create an concrete classes that extends PurchasePower class.
public class Manager extends PurchasePower { @Override protected double getAllowable() { return BASE * 10; } @Override protected String getRole() { return "Manager"; } }
public class Director extends PurchasePower { @Override protected double getAllowable() { return BASE * 20; } @Override protected String getRole() { return "Director"; } }
public class VicePresident extends PurchasePower { @Override protected double getAllowable() { return BASE * 40; } @Override protected String getRole() { return "Vice President"; } }
public class President extends PurchasePower { @Override protected double getAllowable() { return BASE * 60; } @Override protected String getRole() { return "President"; } }
Step 3
Create PurchaseRequest class that will have purchase data.
public class PurchaseRequest { private double amount; private String purpose; public PurchaseRequest(double amount, String purpose) { this.amount = amount; this.purpose = purpose; } public double getAmount() { return amount; } public void setAmount(double amount) { this.amount = amount; } public String getPurpose() { return purpose; } public void setPurpose(String purpose) { this.purpose = purpose; } }
Step 4
Create CheckAuthority class that will test chain of responsibility pattern.
import java.io.InputStreamReader; public class CheckAuthority { public static void main(String[] args) { PurchasePower manager = new Manager(); PurchasePower director = new Director(); PurchasePower vicePresident = new VicePresident(); PurchasePower president = new President(); manager.setSuccessor(director); director.setSuccessor(vicePresident); vicePresident.setSuccessor(president); // press Ctrl + c to end try { while (true) { System.out .println("Enter the amount to check who should approve your expenditure."); System.out.print(">"); double d = Double.parseDouble(new BufferedReader( new InputStreamReader(System.in)).readLine()); manager.processRequest(new PurchaseRequest(d, "General")); } } catch (Exception e) { System.exit(1); } } }
Output of the above program shown below.
Enter the amount to check who should approve your expenditure. >1000 Manager will approve $1000.0 Enter the amount to check who should approve your expenditure. >2000 Manager will approve $2000.0 Enter the amount to check who should approve your expenditure. >4000 Manager will approve $4000.0 Enter the amount to check who should approve your expenditure. >5000 Director will approve $5000.0 Enter the amount to check who should approve your expenditure. >10000 Vice President will approve $10000.0 Enter the amount to check who should approve your expenditure. >20000 President will approve $20000.0 Enter the amount to check who should approve your expenditure. >25000 President will approve $25000.0 Enter the amount to check who should approve your expenditure.
Important Point
- The base class maintains a "next" pointer.
- Each derived class implements its contribution for handling the request.
- If the request needs to be "passed on", then the derived class "calls back" to the base class, which delegates to the "next" pointer.
- The client (or some third party) creates and links the chain (which may include a link from the last node to the root node).
- The client "launches and leaves" each request with the root of the chain.
- Recursive delegation produces the illusion of magic.
Reference: https://en.wikipedia.org/wiki/Chain-of-responsibility_pattern
factorial hundred In the last few days, the “factorial of 100” is one of the top subjects and a lot of maths geeks compute it using voice assistants such as Alexa, Shiri, etc.
ReplyDeletefactorial hundred In the last few days, the “factorial of 100” is one of the top subjects and a lot of maths geeks compute it using voice assistants such as Alexa, Shiri, etc.
factorial hundred In the last few days, the “factorial of 100” is one of the top subjects and a lot of maths geeks compute it using voice assistants such as Alexa, Shiri, etc.