Understanding The Chain of Responsibility Pattern

Nisal Pubudu
Geek Culture
Published in
5 min readMay 26, 2021
Photo by Jon Tyson on Unsplash

Chain of responsibility pattern is a behavioral design pattern that we use to achieve loose coupling in our software design, where a request from the client is passed to a chain of objects to process them. The request will receive through a handler and the objects in the chain will decide themselves who will going to process that request. Each of these objects contain certain type of commands to handle that request. If a particular object cannot handle that request, it will pass the request to the next object in that chain.

Image: Chain of responsibility pattern concept (educative.io)

So, the main purpose of this pattern is avoiding the coupling. As an example, when sending messages to a receiver, sender do not know who the receiver is, and receiver do not know who the sender is. As a result, receiver can perform its task without knowing who send the message and same goes with the sender as well. That means we can decouple sender and receiver through this design pattern.

Structure of the Chain of Responsibility Pattern

Image: UML Representation (programmergirl.com)

As you can see on the UML diagram, it has 3 type of components named as, Client, Handler, and Concrete-Handler.

Handler: It defines an interface for handling the requests. Also, this can be an abstract class which will primarily receive the request and forward the request to chain of handlers.

Concrete handlers: These are responsible for handle the requests they receive. If a particular handler cannot handle the request, it sends the request to its successor.

Client: Sends requests to the first object in the chain that may handle the command.

Note: The request can be sent to any handler in the chain, but it doesn’t have to be the first one.

Use case of Chain of Responsibility Pattern

In this chapter, I will explain how to apply Chain of Responsibility Pattern with a real-world example using Java. Assume, there is company that provide a system for employees to request leave, based on several facts. So, the company will consider those facts before approving their leave. For example, those might be number of days, employee tier (level), and reason for the leave. Based on these facts, the leave request will forward to a specific person (leave handler), who can handle those requests. The person might be a Team Leader, Project Leader, HR, or Manager. If an employee requests a leave for 7 days or less, the Team Leader will handle that request. But before approving the leave request Team Leader checks the employee’s tier. If the employee tier is within the acceptable range, then the Team Leader will approve the leave request.

If an employee requests a leave for 14 days or less, the Team leader cannot handle that request, since he only has authority to approve a leave up to 7 days. In that case the request will be pass to the Project Leader, who have authority to handle that request. Then, he will begin the approval process and its same as the previous one.

However, in the above scenarios they don’t check the reason for requesting a leave. But when it comes to the HR and Manager level, they will check the reason for requesting a leave. If an employee request up to 21 days, the HR will handle that and if its more than 21 days, the Manager will handle that. When they are handling the request, they will check if the reason is a regular, critical, or special one. Then they will approve or deny the request based on those facts.

Now let’s see the implementation of this example.

Step 01

As the first step, I have implemented the “Leave” class. Within the “Leave” class I have defined fields like “numberOfDays”, “empTier”, and “reason.” Those are the facts, that the company going to consider before approving the leave request.

Step 02

As the second step, we have to create the handler class. According to the scenario, I have created an abstract class named as “LeaveHandler.” Then I have created the “LeaveHandler” object within the class, because the handler should know about its successor.

Also, I have created an abstract method that accepts “Leave” class object. As a result, every class that going to extend “LeaveHandler” class must implement this method within their class.

Step 03

Now we have to implement a separate class for each request approver (Concrete Handlers) in this company. As a result, I have created a separate class for Team Leader, Project Leader, HR, and Manager. All these classes extend the “LeaveHandler” class and implement the “applyLeave” method within them.

Also, I have created an Enum to hold the reason types.

As you can see, the “applyLeave” method contains the core logic of these classes. So, whenever a leave request receives to the handler, it will pass to the Team Leader. If the Team Leader has authority to take action on that request, he will process the and give the result (approved/ denied). If he does not have the authority, he will pass it to the next person (Project Leader) in the chain. If no one has authority to take action on a request (if an employee request more than 21 days and reason is “Special”), then it will be passed to the Manager (end of the chain), and he will give the response for that request.

Step 04

At last we can run the application

Output:

Your leave days has been APPROVED by TeamLeader
Your employee Tier level is too low for request 5 days
Your leave days has been APPROVED by Project Leader
Your leave days has been APPROVED by HR
Your leave request has been DENIED by HR
Your leave days has been APPROVED by Manager

If you are interested, you can use the following GitHub link to see my complete implementation of Chain of Responsibility pattern.

So, this is the end of my article and I hope you enjoyed it. Happy Coding👨‍💻.

--

--