Responsibility chain model
preface
- definition
The objects that can handle the same kind of requests are connected into a chain, and the submitted requests are transmitted along the chain. The objects on the chain judge whether they are able to handle the request one by one. If they can, they will be processed, and if not, they will be passed to the next object on the chain. - scene
– when playing cards, take turns
– relay race
– scholarship approval in Universities
– official document approval in the company
Case:
In the company, the approval process for leave is:
If the leave days are less than 3 days, the director shall approve it
If the leave days are more than or equal to 3 days and less than 10 days, the manager shall approve it
Leave for more than or equal to 10 days and less than 20 days shall be approved by the deputy general manager. If it is more than or equal to 20 days and less than 30 days, it shall be approved by the general manager ⑤ if it is more than or equal to 30 days, it will be prompted to refuse
1, Concrete implementation
1. Entity type (leave information)
/** * Encapsulate the basic information of leave * @author Administrator * */ public class LeaveRequest { private String empName; private int leaveDays; private String reason; public LeaveRequest(String empName, int leaveDays, String reason) { super(); this.empName = empName; this.leaveDays = leaveDays; this.reason = reason; } public String getEmpName() { return empName; } public void setEmpName(String empName) { this.empName = empName; } public int getLeaveDays() { return leaveDays; } public void setLeaveDays(int leaveDays) { this.leaveDays = leaveDays; } public String getReason() { return reason; } public void setReason(String reason) { this.reason = reason; } }
2. Abstract handler role
/** * abstract class * @author Administrator * */ public abstract class Leader { protected String name; protected Leader nextLeader; //Successor objects in the responsibility chain public Leader(String name) { super(); this.name = name; } //Set successor objects in the responsibility chain public void setNextLeader(Leader nextLeader) { this.nextLeader = nextLeader; } /** * The core business method for processing requests * @param request */ public abstract void handleRequest(LeaveRequest request); }
3. Specific processor role
package chainOfResponsibility; /** * director * @author Administrator * */ public class Director extends Leader { public Director(String name) { super(name); } @Override public void handleRequest(LeaveRequest request) { if(request.getLeaveDays()<3){ System.out.println("Employees:"+request.getEmpName()+"Leave, days:"+request.getLeaveDays()+",reason:"+request.getReason()); System.out.println("Director:"+this.name+",Approved!"); }else{ if(this.nextLeader!=null){ this.nextLeader.handleRequest(request); } } } }
package chainOfResponsibility; /** * manager * @author Administrator * */ public class Manager extends Leader { public Manager(String name) { super(name); } @Override public void handleRequest(LeaveRequest request) { if(request.getLeaveDays()<10){ System.out.println("Employees:"+request.getEmpName()+"Leave, days:"+request.getLeaveDays()+",reason:"+request.getReason()); System.out.println("Manager:"+this.name+",Approved!"); }else{ if(this.nextLeader!=null){ this.nextLeader.handleRequest(request); } } } }
package chainOfResponsibility; /** * Vice General Manager * @author Administrator * */ public class ViceGeneralManager extends Leader { public ViceGeneralManager(String name) { super(name); } @Override public void handleRequest(LeaveRequest request) { if(request.getLeaveDays()<20){ System.out.println("Employees:"+request.getEmpName()+"Leave, days:"+request.getLeaveDays()+",reason:"+request.getReason()); System.out.println("Vice General Manager:"+this.name+",Approved!"); }else{ if(this.nextLeader!=null){ this.nextLeader.handleRequest(request); } } } }
package chainOfResponsibility; /** * general manager * @author Administrator * */ public class GeneralManager extends Leader { public GeneralManager(String name) { super(name); } @Override public void handleRequest(LeaveRequest request) { if(request.getLeaveDays()<30){ System.out.println("Employees:"+request.getEmpName()+"Leave, days:"+request.getLeaveDays()+",reason:"+request.getReason()); System.out.println("general manager:"+this.name+",Approved!"); }else{ System.out.println("Isn't it"+request.getEmpName()+"Want to resign and ask for leave"+request.getLeaveDays()+"God!"); } } }
4. Testing
package chainOfResponsibility; public class Client { public static void main(String[] args) { Leader a = new Director("Zhang San"); Leader b = new Manager("Li Si"); Leader b2 = new ViceGeneralManager("Li Xiaosi"); Leader c = new GeneralManager("Wang Wu"); //Relationship between organizational responsibility chain and objects a.setNextLeader(b); b.setNextLeader(b2); b2.setNextLeader(c); //Start leave operation LeaveRequest req1 = new LeaveRequest("TOM", 15, "Go back to England to visit relatives!"); a.handleRequest(req1); } }
result:
2, Application scenario
- In Java, exception mechanism is a responsibility chain pattern. A try can correspond to multiple catch es,
When the first catch does not match the type, it automatically jumps to the second catch. - In Javascript language, the bubble and capture mechanism of events. In the Java language, the event processing adopts the observer mode.
- Servlet development, filter chain processing
- In struts 2, the call of interceptor is also a typical responsibility chain mode
summary
The responsibility chain model reduces the coupling between the sender and receiver of the request, so that multiple objects have the opportunity to process the request. A chain can be a line, a tree, a ring... The responsibility chain model requires that commands can only be passed to the next family at the same time, not to more than one next family.
Scenario of using responsibility chain:
- There are multiple objects that can process a request
- You want to submit a request through one of the objects without explicitly specifying the recipient
- The collection of objects that can handle a request should be specified dynamically
Advantages: it is impossible to predict the type of requests from the outside world. If each class encounters a request that it cannot handle, it can just give up.
Disadvantages: low efficiency. Because the completion of a request may have to traverse to the end; Poor scalability, because in the responsibility chain, there must be a unified interface Hadler.