It’s one of behavior design pattern
Chain of responsibility pattern is used to achieve loose
coupling in software design where a request from client is passed to a chain of
objects to process them. Then the object in the chain will decide themselves
who will be processing the request and whether the request is required to be
sent to the next object in the chain or not.
Example: - We know that we can have multiple catch blocks in
a try-catch block code. Here every catch block is kind of a processor to
process that particular exception.
Another real-time scenario was request approval process
Components
in diagram are:
- Handler: An abstract
class or Interface which defines request handling behavior which handles
request
- ConcreteHandlers: Define more specific behavior for handling request, if they can’t handle it, they will simply call super class handle method.
- Client: Instantiates
all concrete handlers and chains them dynamically.
DPRequest.java
package dp;
public class DPRequest {
private String requestType;
private String isItApprovedByLevel2;
private String isItApprovedByLevel1;
public String
getRequestType() {
return requestType;
}
public void
setRequestType(String requestType) {
this.requestType = requestType;
}
public String
getIsItApprovedByLevel2() {
return isItApprovedByLevel2;
}
public void
setIsItApprovedByLevel2(String isItApprovedByLevel2) {
this.isItApprovedByLevel2 =
isItApprovedByLevel2;
}
public String
getIsItApprovedByLevel1() {
return isItApprovedByLevel1;
}
public void
setIsItApprovedByLevel1(String isItApprovedByLevel1) {
this.isItApprovedByLevel1 =
isItApprovedByLevel1;
}
}
Approvals.java
package dp;
public interface Approvals {
public void nextAction(Approvals
next);
public void process(DPRequest
request);
}
Supervisor.java
package dp;
public class Supervisor implements Approvals{
private Approvals next;
@Override
public void nextAction(Approvals
next) {
// TODO Auto-generated
method stub
this.next=next;
}
@Override
public void process(DPRequest
request) {
// TODO Auto-generated
method stub
if("Service
Type".equals(request.getRequestType())){
System.out.println("Supervisor
accepted Service Type");
request.setIsItApprovedByLevel1("Y");
}else if("Leave".equals(request.getRequestType())){
System.out.println("Supervisor
accepted Leave Type");
request.setIsItApprovedByLevel1("Y");
}
next.process(request);
}
}
Accountant.java
package dp;
public class Accountant implements Approvals{
private Approvals next;
@Override
public void nextAction(Approvals
next) {
// TODO Auto-generated
method stub
this.next=next;
}
@Override
public void process(DPRequest
request) {
// TODO Auto-generated
method stub
if("Salary
Advance".equals(request.getRequestType()) && "Y".equals(request.getIsItApprovedByLevel2())){
System.out.println("Accountant
accepted Service Type");
}else{
System.out.println("Salary
Advance request is not approved by Manager");
request.setIsItApprovedByLevel1("N");
next.process(request);
}
}
}
Manager.java
package dp;
public class Manager implements Approvals{
private Approvals next;
@Override
public void nextAction(Approvals
next) {
// TODO Auto-generated
method stub
this.next=next;
}
@Override
public void process(DPRequest
request) {
// TODO Auto-generated
method stub
if("Salary
Advance".equals(request.getRequestType()) && "N".equals(request.getIsItApprovedByLevel1())){
request.setIsItApprovedByLevel2("Y");
System.out.println("Manager
accepted Service Type");
}else if(!"Salary
Advance".equals(request.getRequestType()) && "Y".equals(request.getIsItApprovedByLevel1())){
System.out.println("Manager
accepted Service Type");
}
if(null!=request){
next.process(request);
}
}
}
ChainResponEx.java
package dp;
public class ChainResponEx{
public static void main(String args[]){
DPRequest
request=new DPRequest();
Approvals
s=new Supervisor();
Approvals
a=new Accountant();
Approvals
m=new Manager();
request.setRequestType("Salary
Advance");
// s.nextAction(m);
a.nextAction(m);
m.nextAction(a);
//s.process(request);
a.process(request);
m.process(request);
}
}
Output:-
Salary Advance request is not approved
by Manager
Manager accepted Service Type
Accountant accepted Service Type
- DPRequest
is the actual
request object that will be created by client and passed to chain of
responsibilities.
- Approvals an interface which nextAction method, to handling behavior
which handles request.
- Supervisor
,Accountant and Manager are
concrete sub classes of Approver, which
provide their own specific behavior based on our conditions for approval authorization. If they can’t handle Request, they simply call next.process(request);, which in turn calls method from nextProcess.
- ChainResponEx is actual client which instantiates all
responsibilities and create a chain by setting next approver for each
responsibility.