To avoid the coupling of requester and sender, multiple objects have the chance to receive the request. These objects form a chain, and pass the request along the chain until the request is processed.
Case study:
The OA system of Sunny software company needs to provide a receipt approval module: if the employee's leave days are less than 3 days, the director can approve the receipt; if the employee's leave days are more than or equal to 3 days, less than 10 days, the manager can approve it; if the employee's leave days are more than or equal to 10 days, less than 30 days, the general manager can approve it; if the leave days are more than 30 days, the general manager cannot approve it, and a prompt is given Corresponding rejection information. The model of responsibility chain is used to design the approval module.
/** * @ClassName Leave * @Description: Leave slip * @Author cw * @Date 2020/2/28 **/ public class Leave { private String name; private int dayNum; private String content; public Leave(String name, int dayNum, String content) { this.name = name; this.dayNum = dayNum; this.content = content; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getDayNum() { return dayNum; } public void setDayNum(int dayNum) { this.dayNum = dayNum; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } }
/** * @ClassName ApproverHandler * @Description: Abstract approval processor * @Author cw * @Date 2020/2/28 **/ public abstract class ApproverHandler { protected ApproverHandler nextApproverHandler; public void setNextApproverHandler(ApproverHandler nextApproverHandler) { this.nextApproverHandler = nextApproverHandler; } protected String name; public abstract void processHandler(Leave leave); }
/** * @ClassName DirectorHandler * @Description: Handler (director) * @Author cw * @Date 2020/2/28 **/ public class DirectorHandler extends ApproverHandler { private int handlerDayNum = 3;//Director approval within 3 days public DirectorHandler(String name){ super.name = name; } @Override public void processHandler(Leave leave) { if(leave.getDayNum()<=handlerDayNum){//In line with the scope of approval System.out.println("Director:"+name+""); System.out.println("Approval:"+leave.getName()+"leave"+leave.getDayNum()+"Application for heaven"); System.out.println("Reason for application:"+leave.getContent()); }else{//Pass the false note to the superior leader nextApproverHandler.processHandler(leave); } } }
/** * @ClassName ManagerHandler * @Description: Handler (Manager) * @Author cw * @Date 2020/2/28 **/ public class ManagerHandler extends ApproverHandler { private int handlerDayNum = 10;//Manager approval within 3-10 days public ManagerHandler(String name){ super.name = name; } @Override public void processHandler(Leave leave) { if(leave.getDayNum()<=handlerDayNum){//In line with the scope of approval System.out.println("Manager:"+name+""); System.out.println("Approval:"+leave.getName()+"leave"+leave.getDayNum()+"Application for heaven"); System.out.println("Reason for application:"+leave.getContent()); }else{//Pass the false note to the superior leader nextApproverHandler.processHandler(leave); } } }
/** * @ClassName GeneralManagerHandler * @Description: Handler (General Manager) * @Author cw * @Date 2020/2/28 **/ public class GeneralManagerHandler extends ApproverHandler { private int handlerDayNum = 30;//General manager approval within 10-30 days public GeneralManagerHandler(String name){ super.name = name; } @Override public void processHandler(Leave leave) { if(leave.getDayNum()<=handlerDayNum){//In line with the scope of approval System.out.println("General manager:"+name+""); System.out.println("Approval:"+leave.getName()+"leave"+leave.getDayNum()+"Application for heaven"); System.out.println("Reason for application:"+leave.getContent()); }else{ System.out.println(leave.getName()+"leave"+leave.getDayNum()+"day"); System.out.println("Reason for application:"+leave.getContent()); System.out.println("Leave days exceed the company's leave limit:"+handlerDayNum+"God, general manager"+name+"It can't be approved."); } } }
/** * @ClassName Launcher * @Description: starter * @Author cw * @Date 2020/2/28 **/ public class Launcher { /** * Sunny The OA system of the software company needs to provide a receipt approval module: * If the employee's leave days are less than 3 days, the director can approve the slip; * If the employee's leave days are more than or equal to 3 days and less than 10 days, the manager can approve; * If the leave days of employees are more than or equal to 10 days and less than 30 days, the general manager can approve; * If it is more than 30 days, the general manager cannot approve it, and will prompt the corresponding rejection information. * The model of responsibility chain is used to design the approval module. * @param args */ public static void main(String[] args) { Leave leave = new Leave("Eight quit",31,"Gao Laozhuang gets married");//Leave slip DirectorHandler directorHandler = new DirectorHandler("Sha Seng");//director ManagerHandler managerHandler = new ManagerHandler("name of a fictitious monkey with supernatural powers");//manager GeneralManagerHandler generalManagerHandler = new GeneralManagerHandler("Tang Seng");//General manager directorHandler.setNextApproverHandler(managerHandler);//Director sets up superior leaders managerHandler.setNextApproverHandler(generalManagerHandler);//Manager sets up superior leaders directorHandler.processHandler(leave);//Director begins to process } }
Summary of responsibility chain mode
The responsibility chain mode organizes the handler of the request by establishing a chain, and the request will be delivered along the chain. The sender of the request does not need to know when, where and how the request is processed, which realizes the decoupling between the sender and the handler of the request. In software development, if there are multiple objects that can handle the same request, the responsibility chain mode can be applied, such as creating a filter chain in Web application development to filter the request data, implementing hierarchical approval of official documents in workflow system, etc. using the responsibility chain mode can better solve such problems.
1. Main advantages
The main advantages of the responsibility chain model are as follows:
(1) The responsibility chain mode makes an object do not need to know which other object processes its request. The object only needs to know that the request will be processed. Neither the receiver nor the sender has the clear information of the other party, and the object in the chain does not need to know the structure of the chain. The client is responsible for the creation of the chain, which reduces the coupling degree of the system.
(2) The request processing object only needs to maintain a reference to its successor, and does not need to maintain its reference to all candidate processors, which can simplify the interconnection of objects.
(3) When assigning responsibility to an object, the responsibility chain can give us more flexibility. We can add or change the responsibility of processing a request by dynamically adding or modifying the chain at runtime.
(4) Adding a new specific request handler to the system does not need to modify the original system code, but only needs to rebuild the chain on the client side, which is in line with the "open close principle".
2. Main disadvantages
The main disadvantages of the responsibility chain model are as follows:
(1) Since a request has no clear receiver, there is no guarantee that it will be processed. The request may not be processed all the way to the end of the chain. A request may not be processed because the responsibility chain is not configured correctly.
(2) For a relatively long responsibility chain, the processing of the request may involve multiple processing objects, and the system performance will be affected to some extent, and it is not convenient for code debugging.
(3) If the chain is not built properly, it may cause a circular call, which will cause the system to fall into a dead cycle.
3. Applicable scenarios
Consider using the chain of responsibility model when:
(1) There are multiple objects that can process the same request. The specific object to process the request is to be determined at runtime. The client only needs to submit the request to the chain, and does not need to care about who the request processing object is and how it is processed.
(2) Submit a request to one of multiple objects without explicitly specifying the recipient.
(3) A set of objects can be dynamically specified to process the request. The client can dynamically create a responsibility chain to process the request, and can also change the order of processors in the chain.