Introduction
In Java, to make the code more reliable we should design our code efficiently which can be done by applying design methodologies such as OOPs, OOAD, design principles, and patterns into applications.
Chain of Responsibility pattern is a behavioral design pattern that actually makes the code lose coupling. It decouples the sender of the request to the receiver, where the chain of objects are there to process the request and the request used to starts or process with the first object in the chain, it proceeds if that object has the solution otherwise the request is forwarded to next object in the chain in order to handle or process that request. This chaining will happen until finding the solution object is in the chain.
GOF states that – it “Gives more than one object an opportunity to handle a request by linking receiving objects together.”
Handler – interface to handle the requests
Concrete Handler – A request handler that handles the request that they are responsible for, otherwise it sends the request to its successor.
Client – send the request to the handler to process the request. The first handler object in the chain would be invoked by the client.
Fore.g.
java.util.logging.Logger, javax.servlet.Filter are the examples that are followed by a chain of responsibility design pattern.
Let us take an example of Gmail, where we could see the mails are categorized as Primary, Social, and Promotion.
Social – Emails from Facebook, Twitter, Google plus are in the social category
Promotion – Emails from Paytm, Flipkart, Amazon offers are in the promotion category
Primary – Other emails from people and friends are companies are in the primary category
We can also have our own folder or category or rule for the basis of the incoming email on the subject, from, to, and all.
So, how could we do this in code with good design?
// Handler interface
public interface GmailHandler {
public void setNext(GmailHandler gmailHandler); //to set next handler
public void handleRequest(Email email); //to handle or process the emails
}
// Request object
public class Email {
private boolean is Social;
private boolean is Promotion;
private boolean is Primary;
private Boolean is Spam;
public boolean is Social() {
return is Social; // returns true when emails from facebook, twiiter, google plus
}
public boolean is Promotion() {
return is Promotion; // returns true when emails from paytm, flipkart, amazon offers
}
public boolean is Primary () {
return is Primary; // returns true when emails not from social and shopping sites
}
public boolean is Spam() {
return is Spam;
}
// more members and methods on content of email and other details
}
// Concrete Handler or Request Handler
public interface SocialEmaiHandler {
private GmailHandler handler;
public void setNext(GmailHandler handler) {
this.handler = handler;
}
public void handleRequest(Email email) {
if(email.isSocial()) {
// proceeds or handles social email contents, keeps in social category
} else {
handler.handleRequest(); // proceeding with next handler in the chain
}
}
}
// Concrete Handler or Request Handler
public interface PromotionEmailHandler {
private GmailHandler handler;
public void setNext(GmailHandler handler) {
this.handler = handler;
}
public void handleRequest(Email email) {
if(email.isPromotion()) {
// proceeds or handles promotion email contents, keeps in promotion category
} else {
handler.handleRequest(); // proceeding with next handler in the chain
}
}
}
// Concrete Handler or Request Handler
public interface PrimaryEmailHandler {
private GmailHandler handler;
public void setNext(GmailHandler handler) {
this.handler = handler;
}
public void handleRequest(Email email) {
if(email.isPrimary()) {
// proceeds or handles primary email contents, keeps in primary category
} else {
handler.handleRequest(); // proceeding with next handler in the chain
}
}
}
// Client
public class EmailClient {
private GmailHandler handler;
public EmailClient() {
createProcessChain();
}
public void addRule(GmailHandler handler){
if(this.handler == null)
this.handler = handler;
else
this.handler.setNext(handler);
}
public void sendRequest(Email email){
this.handler.handleRequest(email);
}
public void createProcessChain() {
addRule(new SocialEmailHandler());
addRule(new PromotionEmailHandler());
addRule(new PrimaryEmailHandler());
}
public static void main(String[] aa){
EmailClient client = new EmailClient();
Email email = new Email();
email.setIsPromotion(true);
client.sendRequest(email);
Email email = new Email();
email.setIsPrimary(true);
client.sendRequest(email);
Email email = new Email();
email.setIsSocial(true);
client.sendRequest(email);
}
}
Conclusion:
Just think that, if we didn’t follow this chain of responsibility design pattern how would we achieve this solution? We would write if and else if block on each case or category!!?? If we do so, it creates an n-path complexity problem to our code and it is very difficult to change the code to adapt a new feature i.e. each time we have to rework with the implementation.
So, the Chain of responsibility pattern helps us to make the code loose coupling and easy to adopt a new feature i.e. if we want to add a new rule or category like spam to email simply we can add a new concrete handler called SpamEmailHandler that implements Handler interface and most importantly we are adding the feature to our code without touching the existing implementation.
As you now know that chain of responsibility is a behavioral design pattern used by Java outsourcing company professionals to design the code. Any point you did not get can be asked in comments.
Related Articles:
How to Use Spring Batch and Connect It to Database in Java Development?How To Benefit Out Of Mobile Responsive Java Application Development And Make It Big?