Overview
Chain of Responsibility Pattern can be used when we want to give more than one object a chance to handle a request. The pattern can be used to achieve loose coupling in software design where the request can be passed through a chain of objects to process them, Based on state of chain object it will handle the request or pass it to the next chain object.

As per the diagram, each request pass through the chain of handlers and it will flow through the chain until it gets handled by any of the handler.
Let’s understand with Example
ABC Organization has been getting more email than they can handle since the release of the Java powered Gumball Machine. From their own analysis they get four kinds of email: fan mail from customers that love the new game, complaints from parents whose kids are addicted to the game, requests to put machines in new locations. They also get a spam mails.
All fan mail needs to go straight to the CEO, all complaints go to the legal department and all requests for new machines go to business development. Spam needs to be deleted.

Implementation
We have created
Step 1 :
Create a Mail.java class
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
package com.codenuclear; public class Mail { private String subject; public Mail(String subject) { this.subject = subject; } public String getSubject() { return subject; } public void setSubject(String subject) { this.subject = subject; } } |
Step 2 :
Create a base Interface.
Handler.java
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
package com.codenuclear; public interface Handler { String SPAM_MAIL="SPAM_MAIL"; String FAN_MAIL="FAN_MAIL"; String COMPLAINT_MAIL="COMPLAINT_MAIL"; String NEW_LOC_MAIL="NEW_LOC_MAIL"; void setNextChain(Handler nextChain); void forwardMail(Mail mailObj); } |
Step 3 :
Create a chain Handler implementing base Inteface.
SpamHandler.java
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
package com.codenuclear; public class SpamHandler implements Handler { private Handler chain; @Override public void setNextChain(Handler nextChain) { this.chain=nextChain; } @Override public void forwardMail(Mail mailObj) { /* * Checking a mail subject and forwarding to next Chain Handler. */ if(mailObj.getSubject().equalsIgnoreCase(Handler.SPAM_MAIL)){ System.out.println("Mail Deleted."); }else{ this.chain.forwardMail(mailObj); } } } |
0 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 |
package com.codenuclear; public class FanHandler implements Handler { private Handler chain; @Override public void setNextChain(Handler nextChain) { this.chain=nextChain; } @Override public void forwardMail(Mail mailObj) { /* * Checking a mail subject and forwarding to next Chain Handler. */ if(mailObj.getSubject().equalsIgnoreCase(Handler.FAN_MAIL)){ System.out.println("Forwarding Mail to CEO."); }else{ this.chain.forwardMail(mailObj); } } } |
0 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 |
package com.codenuclear; public class ComplaintHandler implements Handler { private Handler chain; @Override public void setNextChain(Handler nextChain) { this.chain=nextChain; } @Override public void forwardMail(Mail mailObj) { /* * Checking a mail subject and forwarding to next Chain Handler. */ if(mailObj.getSubject().equalsIgnoreCase(Handler.COMPLAINT_MAIL)){ System.out.println("Forwarding Mail to Legal Department."); }else{ this.chain.forwardMail(mailObj); } } } |
0 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 |
package com.codenuclear; public class NewLocHandler implements Handler { private Handler chain; @Override public void setNextChain(Handler nextChain) { this.chain=nextChain; } @Override public void forwardMail(Mail mailObj) { /* * Checking a mail subject. */ if(mailObj.getSubject().equalsIgnoreCase(Handler.NEW_LOC_MAIL)){ System.out.println("Forwarding Mail to Business Development Group."); }else{ this.chain.forwardMail(mailObj); } } } |
Step 4 :
Create different types of chain Handler and set next Handler to form a chain. Next handler in each Handler represents the part of the chain.
0 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 |
package com.codenuclear; public class MailChain { private Handler chain; /* * Forming a chain */ public MailChain(){ this.chain=new SpamHandler(); Handler fanHandlerObj=new FanHandler(); Handler complaingtHandlerObj=new ComplaintHandler(); Handler newLocngtHandlerObj=new NewLocHandler(); chain.setNextChain(fanHandlerObj); fanHandlerObj.setNextChain(complaingtHandlerObj); complaingtHandlerObj.setNextChain(newLocngtHandlerObj); } public static void main(String s[]) { MailChain mailChainObj =new MailChain(); /* * calling a chain with Different Subject mail. */ mailChainObj.chain.forwardMail(new Mail("SPAM_MAIL")); mailChainObj.chain.forwardMail(new Mail("FAN_MAIL")); mailChainObj.chain.forwardMail(new Mail("COMPLAINT_MAIL")); mailChainObj.chain.forwardMail(new Mail("NEW_LOC_MAIL")); } } |
Output :
As email is received, it is passed to the handler: the SpamHandler. If the SpamHandler can’t handle the request, It is passed on to the FanHandler. And so on…
Benefits of Chain of Responsibility Pattern
- Decouples the sender of the request and its receivers.
- Simplifies our object because it doesn’t have to know the chain’s structure and keep direct references to its memebers.
- Allows to add or remove responsibilities dynamically by changing the memebers or order of the chain.
Drawbacks of Chain of Responsibility Pattern
- Execution of the request isn’t guaranteed; it may fail off the end of the chain if no object handles it.
- Can be hard to observe the run-time characteristics and debug.
How about combining COR with modified Builder pattern and ending up with something like:
…
chain.getChainBuilder().setNextChain(fanHandlerObj).setNextChain(complaingtHandlerObj).setNextChain(newLocngtHandlerObj).build();
How about that 🙂
Hi Bali,
Glad to know that you have inputs here.
We generally follow a practice to write a code which is readable and understandable to readers. But what you are saying is also right way to build a chain.