Java Chain of Responsibility Design Pattern Example
1. Introduction
In this article, we will discuss about a widely used Design pattern – Java Chain of Responsibility Design Pattern. In the name itself it suggests that, the Chain of responsibility design pattern generates a chain of receiver objects for a request. This pattern separates the sender and receiver for a request based on the type of request. This design pattern is a classification of behavioural design patterns. The pattern is a explanation, used and tested solution for a recognised issue. Design patterns are used more than once. Software design patterns developed as a area of study only when object oriented programming came into existence. An object oriented programming structure and the design patterns both are impossible to separate.
There are two things we take into consideration when dealing with design patterns. First Design and then pattern. There should be a useful design for every problem and whenever the problem takes place quite often, we create a reusable solution to this problem. This reusable solution is known as design pattern. A design is considered to be good if it helps to develop a software that is behaviourally, economically and socially applicable and with less effort can accommodate any modification.
2. Java Design Patterns
Java design patterns are classified into three important and widely used sub- categories, which are discussed below and elaborated.
2.1 Creational Pattern
The Creational design patterns are divided into six different design types. In class instantiation, Creational design patterns are used. These design patterns provide supple ways of creating objects, which helps to reduce dependencies between classes and increase code reusability. Creational design patterns in particular can offer a great adaptability as to which objects are created, and how these objects are created and how they are initialised. These design patterns are further divided into class and object creation patterns. When working with class-creation patterns they effectively use inheritance in the installation procedure, on the other hand object-creation patterns effectively use delegation to complete the work. These design patterns are used to build objects such that they can be decoupled from their performing structure.
2.2 Structural Pattern
Structural Design Pattern provides seven different types of patterns. These design patterns visualise us how to flexibly and extensibly integrate various elements of a application. Structural patterns help us and guarantee that when one of the elements or system parts changes, the whole structure does not necessarily need to be changed. These patterns relate mainly to class and object integration. Structural design patterns define how objects can be integrated to provide new features. These design patterns are used to construct large object structures between many different objects.
2.3 Behavioural Pattern
This pattern defines eleven different pattern categories for interacting with other objects. These design patterns relate to class-to-object communication. Behavioural design patterns are those patterns which are concerned for communication between objects most specifically. These design patterns are used to handle algorithms, relationships, and responsibilities between objects.
In this article, we are going to discuss about one of the widely used behavioural patterns – Chain of Responsibility Design Pattern. If we talk about the definition it says, In software engineering, this design pattern produce more than one object an opportunity to handle a request by connecting receiving objects together. This pattern is a type of behavioural pattern because of which it improves the program’s execution process. This article would explain the concept about the Chain of Responsibility design pattern with a real life example. The following section logically represents the pattern to explain every component of the Chain of responsibility design pattern. We will also implement a Chain of responsibility design pattern in Java code.
3. Understanding the Chain of responsibility design pattern
Now, let us understand Chain of responsibility design pattern. It is used to gain lose coupling in software application when a customer request from client is transferred to a chain of objects for processing. The object in the chain then decides who will process the request and whether or not the request must be sent to the next object in the chain.
In simple words, for understanding this design pattern let us take an example, we all have an idea that in a try-catch block code we can have multiple catch blocks. Here each catch block is a processor that processes this specific exception or error. Therefore, whenever an exception or error occurs in the try block, then it is sent to the first catch block. In case if the catch block is not able to process it, then the request will be forwarded to the next object in a chain, i.e. the next catch block. At last even if the last catch block can not be processed, the exception or error to the calling program is thrown outside the chain of objects.
In Chain of responsibility design pattern each and every processing object in the chain is responsible for a specific type of command, and the processing is completed, the command is forwarded to the next processor in the chain.
Let’s look at the UML class diagram to see the Chain of responsibility design pattern architecture before going into more detail.
In the above UML Class Diagram of Chain of responsibility Design Pattern it consists of the following classes, interfaces and objects:
- Handler : In the above diagram Handler is an interface which will essentially acquire the request and send the request to chain of handlers.It only refers to the first handler in the chain and knows nothing about the remaining handler.
- ConcreteHandler1 and 2: ConcreteHandler1 and Concretehandler2 are original request handlers connected in sequential order.
- Client : Client is a request creator and this will access the handler to handle it.
In detail, the handler defines the interface to handle requests while the ConcreteHandler1
and ConcreteHandler2
both process the requests for which they are responsible. In case the ConcreteHandler1
can not handle the request, the request is passed on to the ConcreteHandler2
which is linked to ConcreteHandler1
. The chain objects just need to know how to transmit the request to other objects. This decoupling is an enormous advantage because at run time we can modify or can perform some changes to the chain.
3.1 Real Life Example
Before implementing Chain of responsibility design pattern let us take a real life example to understand this design pattern in more detail. For understanding this design pattern in detail there are two scenario are as follows:
- Only one receiver in the chain handles the request: In this scenario we will take an example of Quiz App. In Quiz App, assume there is a quiz master who is asking questions to the quiz players. In the above figure there are three players who are playing quiz game there names are John, David, Raj. Whenever quiz master asks questions to the players if player 1 (John) knows the answer then he will answer it and the process stops here. In case if john does not know the answer then he will pass chance to the next player (David) to give answer and if David has answer then will answer the question. Similarly, if David does not know the answer then he will pass to the third player (Raj) for answering. If Raj knows the answer then round 1 of Quiz game is finished.
- One or more receivers in the chain handles the request: In this scenario we take an example of ATM machine. Let’s suppose an user wants to withdraw some amount of money from the nearest ATM. Here in the above figure an user (John) inserts his debit card into the ATM machine and enter his pin number and amount of money he wants. John enters 455 rupees in place of amount field then ATM sends request to hundred rupees handler it will give four pieces of hundred rupees notes. For remaining 55 rupees hundred rupees handler sends request to fifty rupees handler it gives one piece of fifty rupees note then fifty rupees handler sends request to five rupees handler it gives one five rupees note. The twenty rupees handler will not do any operation as there is no requirement of twenty rupees. Here in the above diagram rupees handlers are working as a chain of objects.
4. Implementing Chain of responsibility design pattern
Let us now move forward and try to create a simple example to see how the Chain of responsibility design pattern can be implemented using java programming. Assume an example of Torrent Bill Payment Kiosk where customers can pay their electricity bill instead of standing in the queue. If any customer wants to pay his/her electricity bill via kiosk then he/she has to enter their customer number and have to place their money in cash collector. Suppose the amount of money is 1745 then inside the Kiosk 500 rupees handler performs operation and fetches two three notes of five hundred and passes the request to 100 rupees handler it performs operation and fetches two notes of one hundred. Similarly for 10 rupees handler it fetches four notes of ten rupees and 5 rupees handler it fetches one note of five rupees.
RupeesHandler.java
public abstract class RupeesHandler { RupeesHandler rupeesHandler; public void nextHandler( RupeesHandler rupeesHandler) { this.rupeesHandler= rupeesHandler; } public abstract void fetchRupees( long givenAmount ); }
In above program, we have created an abstract class called RupeesHandler
. Inside this abstract class we have implemented two functions they are nextHandler()
and fetchRupees()
. fetchRupees()
is an abstract method.
FiveHundredRupeesHandler.java
public class FiveHundredRupeesHandler extends RupeesHandler { public void fetchRupees(long givenAmount) { long numberofNotesToBeFetched = givenAmount / 500; if (numberofNotesToBeFetched > 0) { if(numberofNotesToBeFetched >1) { System.out.println(numberofNotesToBeFetched + " ,Five Hundred Rupees notes are Fetched by FiveHundredRupeesHandler \n"); } else { System.out.println(numberofNotesToBeFetched + " ,Five Hundred Rupees note is Fetched by FiveHundredRupeesHandler \n"); } } long pendingRupeesToBeProcessed = givenAmount % 500; if (pendingRupeesToBeProcessed > 0) { rupeesHandler.fetchRupees(pendingRupeesToBeProcessed); } } }
In the above program, we have created FiveHundredRupeesHandler
class which extends RupeesHandler
class. Inside this class we have implemented fetchRupees()
method which is defined in RupeesHandler
class. In fetchRupees()
method we implemented all the operations regarding payment of five hundred rupees.
HundredRupeesHandler.java
public class HundredRupeesHandler extends RupeesHandler { public void fetchRupees(long givenAmount) { long numberofNotesToBeFetched = givenAmount / 100; if (numberofNotesToBeFetched > 0) { if(numberofNotesToBeFetched >1) { System.out.println(numberofNotesToBeFetched + " ,Hundred Rupees notes are Fetched by HundredRupeesHandler \n"); } else { System.out.println(numberofNotesToBeFetched + " ,Hundred Rupees note is Fetched by HundredRupeesHandler \n"); } } long pendingRupeesToBeProcessed = givenAmount % 100; if (pendingRupeesToBeProcessed > 0) { rupeesHandler.fetchRupees(pendingRupeesToBeProcessed); } } }
In the above program, we have created HundredRupeesHandler
class which extends RupeesHandler
class. Inside this class we have implemented fetchRupees()
method which is defined in RupeesHandler
class. In fetchRupees()
method we implemented all the operations regarding payment of hundred rupees.
FiftyRupeesHandler.java
public class FiftyRupeesHandler extends RupeesHandler { public void fetchRupees(long givenAmount) { long numberofNotesToBeFetched = givenAmount / 50; if (numberofNotesToBeFetched > 0) { if(numberofNotesToBeFetched >1) { System.out.println(numberofNotesToBeFetched + " ,Fifty Rupees notes are Fetched by FiftyRupeesHandler \n"); } else { System.out.println(numberofNotesToBeFetched + " ,Fifty Rupees note is Fetched by FiftyRupeesHandler \n"); } } long pendingRupeesToBeProcessed = givenAmount % 50; if (pendingRupeesToBeProcessed > 0) { rupeesHandler.fetchRupees(pendingRupeesToBeProcessed); } } }
In the above program, we have created FiftyRupeesHandler
class which extends RupeesHandler
class. Inside this class we have implemented fetchRupees()
method which is defined in RupeesHandler
class. In fetchRupees()
method we implemented all the operations regarding payment of fifty rupees.
TwentyRupeesHandler.java
public class TwentyRupeesHandler extends RupeesHandler { public void fetchRupees(long givenAmount) { long numberofNotesToBeFetched = givenAmount / 20; if (numberofNotesToBeFetched > 0) { if(numberofNotesToBeFetched >1) { System.out.println(numberofNotesToBeFetched + " ,Twenty Rupees notes are Fetched by TwentyRupeesHandler \n"); } else { System.out.println(numberofNotesToBeFetched + " ,Twenty Rupees note is Fetched by TwentyRupeesHandler \n"); } } long pendingRupeesToBeProcessed = givenAmount % 20; if (pendingRupeesToBeProcessed > 0) { rupeesHandler.fetchRupees(pendingRupeesToBeProcessed); } } }
In the above program, we have created TwentyRupeesHandle
r class which extends RupeesHandler
class. Inside this class we have implemented fetchRupees()
method which is defined in RupeesHandler
class. In fetchRupees()
method we implemented all the operations regarding payment of twenty rupees.
FiveRupeesHandler.java
public class FiveRupeesHandler extends RupeesHandler { public void fetchRupees(long givenAmount) { long numberofNotesToBeFetched = givenAmount / 5; if (numberofNotesToBeFetched > 0) { if(numberofNotesToBeFetched >1) { System.out.println(numberofNotesToBeFetched + " ,Five Rupees notes are Fetched by FiveRupeesHandler \n"); } else { System.out.println(numberofNotesToBeFetched + " ,Five Rupees note is Fetched by FiveRupeesHandler \n"); } } long pendingRupeesToBeProcessed = givenAmount % 5; if (pendingRupeesToBeProcessed > 0) { rupeesHandler.fetchRupees(pendingRupeesToBeProcessed); } } }
In the above program, we have created FiveRupeesHandler
class which extends RupeesHandler
class. Inside this class we have implemented fetchRupees()
method which is defined in RupeesHandler
class. In fetchRupees()
method we implemented all the operations regarding payment of five rupees.
Kiosk.java
public class Kiosk { private static FiveHundredRupeesHandler fivehundredRupeesHandler = new FiveHundredRupeesHandler(); private static HundredRupeesHandler hundredRupeesHandler = new HundredRupeesHandler(); private static FiftyRupeesHandler fiftyRupeesHandler = new FiftyRupeesHandler(); private static TwentyRupeesHandler twentyRupeesHandler = new TwentyRupeesHandler(); private static FiveRupeesHandler fiveRupeesHandler = new FiveRupeesHandler(); static { // Construct the chain of Rupees Handlers fivehundredRupeesHandler.nextHandler(hundredRupeesHandler); hundredRupeesHandler.nextHandler(fiftyRupeesHandler); fiftyRupeesHandler.nextHandler(twentyRupeesHandler); twentyRupeesHandler.nextHandler(fiveRupeesHandler); } public void payment( long givenAmount ) { fivehundredRupeesHandler.fetchRupees(givenAmount); } }
In the above code, we have created a class called Kiosk
. Inside this class we have created objects of all the Rupees Handlers and constructed a chain of Rupees handlers using nextHandler()
method. Also, we implemented payment()
method.
ChainOfResponsibility.java
public class ChainOfResponsibility { public static void main( String[] args ) { Kiosk kiosk = new Kiosk(); System.out.println("\n ----------------Paid Amount 1755-----------------------\n"); kiosk.payment(1755); System.out.println("\n ----------------Paid Amount 2275-----------------------\n"); kiosk.payment(2275); } }
In the above code, we have created class known as ChainOfResponsibility
in which we implemented main()
method. Inside the main()
method we created a object of Kiosk
Class and called payment()
method using that object.
5. Benefits of using Chain of responsibility Design Pattern
Until now, we have discussed about the Chain of responsibility design pattern, how it is implemented using java program and its real life example. Let us now discuss some of its benefits. The main advantages of Chain of responsibility design pattern are:
- Chain of responsibility design pattern increase flexibility of object to which responsibility is assigned. On changing the objects inside the chain or changing in their order, permits dynamic adding or deleting responsibility.
- It has the benefit of reducing the coupling degree between the sender of the request and its receivers.
- This design pattern allows a number of classes to behave as same; events created in one class can be sent to other handler classes by composition.
- Chain of responsibility pattern increase the processing of new class requests very conveniently.
- In this design pattern the objects in the chain does not need to know the structure of the chain. The objects are simplified.
6. Use of Chain of responsibility Design Pattern
As we know with so many design patterns to choose from when writing a program, it is difficult to decide which one to use, so some situations are more effective when using the chain of responsibility design pattern:
- This design pattern can be used when we want to decouple a request between sender and receiver. Due to this it facilitates many functionalities.
- This pattern can also be used when multiple objects in the chain are designed to handle a request at run time. It improves efficiency.
- Chain of responsibility pattern is used when we do not want to explicitly specify handlers in our code.
- It is used when we want to ask for one of several objects in the chain without explicitly specifying the receiver.
7. Demerits of Chain of responsibility Design Pattern
In this section we will explain some of the disadvantages of the Chain of responsibility design pattern:
- One of the most important disadvantage of this pattern is the request received from the sender object must not be guaranteed.
- Another disadvantage is it degrades the system’s performance, and it is not easy to debug code and to call a cycle.
- Due to debugging, it may not be easy to observe the operating characteristics.
8. Java Chain of responsibility Design Pattern – Conclusion
In this article, we covered the Chain of responsibility design pattern. This pattern is useful for modelling requests and handling events if we do not know the number and type of handlers in advance. The event – based systems, purchasing systems and shipping systems, ATM, Bill Payment Kiosk are real life examples that places well with the chain of responsibility pattern. Thus it concludes that Chain of Responsibility pattern allows multiple objects in a chain to handle a request object. The request flows through the chain until it is handled by a link in the chain. The chain of responsibilities design pattern is a very powerful pattern. A chain of chains can also be implemented, creating a multi- dimensional structure.
9. Download the Source Code
That was Java Chain of Responsibility Design Pattern Example.
You can download the full source code of this example here: ChainOfResponsibilityDesignPattern.zip
Thank you for design pattern of java