Chain of Responsibility – Behavioral Design Pattern
The Chain of Responsibility Pattern comes under Behavioral design pattern, the main motive of this pattern is to accomplish loose coupling in Software design process where the client request is passes to series (CHAIN) of objects to process the client request. If one object is not able to handle the request then it will pass the request to the next object (Loose coupling) and so on.
So in this chain of objects, each object is given some responsibility and once its processing is complete, that object will forward the command to the next object in the chain.
In this type of pattern there may be a possibility of many handler objects and many client requests which must be handled by these handlers. So it’s important to efficiently process the client requests.
<Here are ALL Java Design Patterns, explained in detail with examples>
Chain of Responsibility Pattern by Example
Generally, each company has its own website on which there will be a contact section where email id is given, which can be used by different people for different queries like some people may contact for job related things, some may contact to give feedback, some may contact for business related things Etc.
So in company there may be different departments which handles different queries like job queries can be handled by Recruitment Dept, General feedback, complaints can be handled by HR dept, Business related queries by Business Development Dept etc.
By considering above scenario we are going to write down java program to implement chain of responsibility pattern.
IMPLEMENTATION:
Whenever new Email comes our handler checks the email subject and forwards it to particular handler. It will pass from chain of handlers.
In this java program, we created 4 handlers.
- For Spam mail : spam mails are deleted by SpamHandler
- For job related mail : this mail is forwarded to RecHandler handler
- For general enquiry or feedback mail. : this mail forwarded to OtherMailHandler
- For business related mail forwarded to NewBusHandler
Here, we created handler interface where setNextChain() method is used to form a chain between different handlers and forwardEMail() method is used to forward the mail to particular dept.
In this example there are 4 chain handlers, all implement the Handler Interface. Every chain Handler checks EMail subject and so it will handle the request or it will pass it to the next handler as per the sequence set by setNextChain() method.
Lets define a simple Email class to hold the subject only for our demonstration.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public class Email { private String mailsubject; public Email(String mailsubject) { this.mailsubject = mailsubject; } public String getSubject() { return mailsubject; } public void setSubject(String mailsubject) { this.mailsubject = mailsubject; } } |
Now define a interface Handler, which will be implemented by different classes
1 2 3 4 5 6 7 8 9 10 11 |
public interface Handler { String SPAM_MAIL = "SPAM_MAIL"; String REC_MAIL = "REC_MAIL"; String OTHER_MAIL = "OTHER_MAIL"; String NEW_BUSINESS_MAIL = "NEW_BUSINESS_MAIL"; void setNextChain(Handler nextChain); void forwardEMail(Email mailObj); } |
NewBusHandler
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
public class NewBusHandler implements Handler { private Handler chain; @Override public void setNextChain(Handler nextChain) { this.chain = nextChain; } @Override public void forwardEMail(Email mailObj) { if (mailObj.getSubject().equalsIgnoreCase(Handler.NEW_BUSINESS_MAIL)) // checking mail subject and then // forwarding to next chain handller { System.out.println("Its a Business mail :Forwarding Mail to Business Development Department."); } else { this.chain.forwardEMail(mailObj); } } } |
OtherMailHandler
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
public class OtherMailHandler implements Handler { private Handler chain; @Override public void setNextChain(Handler nextChain) { this.chain = nextChain; } @Override public void forwardEMail(Email mailObj) { if (mailObj.getSubject().equalsIgnoreCase(Handler.OTHER_MAIL)) // checking mail subject and then forwarding to // next chain handller { System.out.println("Forwarding Mail to HR Department."); } else { this.chain.forwardEMail(mailObj); } } } |
RecHandler
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
public class RecHandler implements Handler { private Handler chain; @Override public void setNextChain(Handler nextChain) { this.chain = nextChain; } @Override public void forwardEMail(Email mailObj) { if (mailObj.getSubject().equalsIgnoreCase(Handler.REC_MAIL)) // checking mail subject and then forwarding to // next chain handller { System.out.println("Its a Job related mail :Forwarding Mail to Recruitment Dept"); } else { this.chain.forwardEMail(mailObj); } } } |
SpamHandler
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
public class SpamHandler implements Handler { private Handler chain; @Override public void setNextChain(Handler nextChain) { this.chain = nextChain; } @Override public void forwardEMail(Email mailObj) { if (mailObj.getSubject().equalsIgnoreCase(Handler.SPAM_MAIL)) // checking mail subject and then forwarding to // next chain handller { System.out.println("its a SPAM mail : Mail Deleted."); } else { this.chain.forwardEMail(mailObj); } } } |
Running the example
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 |
public class MailChain { private Handler chain; public MailChain() { this.chain = new SpamHandler(); Handler recHandlerObj = new RecHandler(); Handler othermailHandlerObj = new OtherMailHandler(); Handler newbusinessHandlerObj = new NewBusHandler(); chain.setNextChain(recHandlerObj); recHandlerObj.setNextChain(othermailHandlerObj); othermailHandlerObj.setNextChain(newbusinessHandlerObj); } // calling a chain with different email subject public static void main(String s[]) { MailChain mailChainObj = new MailChain(); mailChainObj.chain.forwardEMail(new Email("SPAM_MAIL")); mailChainObj.chain.forwardEMail(new Email("REC_MAIL")); mailChainObj.chain.forwardEMail(new Email("OTHER_MAIL")); mailChainObj.chain.forwardEMail(new Email("NEW_BUSINESS_MAIL")); } } |
Output
1 2 3 4 |
its a SPAM mail : Mail Deleted. Its a Job related mail :Forwarding Mail to Recruitment Dept Forwarding Mail to HR Department. Its a Business mail :Forwarding Mail to Business Development Department. |
CONCLUSION:
This is all about Chain of Responsibility pattern, which defines a chain or list of handlers, each of handlers is able to process client request and whenever the request is submitted to this chain it is passed to the very first handler in the list to process it and pass the request along the chain until an object handles it. One thing is important regarding this pattern is that don’t use this pattern when every request is handled by only one handler.
Hai john,
this is supriya,
I m impressed for this is easy to understand and clearly written.
This is easy to understand and clearly written. Thanks for the spamcheck tutorial Supriya.