一、责任链模式介绍
1、定义
- 责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链,每个接收者都包含对另一个接收者的引用,如果一个对象不能处理该请求,那么它会把请求传给下一个接收者,依此类推;
- 责任链模式避免了请求的发送者和接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连成一条链,并且沿着这条链传递请求,直到有对象处理它为止。
2、优点
- 降低耦合度。它将请求的发送者和接收者解耦;
- 简化了对象,使得对象不需要知道链的结构;
- 增强给对象指派职责的灵活性,允许动态地新增或者删除责任链
- 增加新的请求处理类方便
3、缺点
- 不能保证请求一定被接收;
- 系统性能将受到一定影响,调试时不方便,可能会造成循环调用;
4、应用实例
- 红楼梦中的"击鼓传花";
- JS 中的事件冒泡;
- JAVA WEB 中 Apache Tomcat 对 Encoding 的处理,Struts2 的拦截器,jsp servlet 的 Filter;
5、使用场景
- 有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定;
- 在不明确指定接收者的情况下,向多个对象中的一个提交一个请求;
- 可动态指定一组对象处理请求。
二、代码示例
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class LeaveRequest {
/**天数*/
private int leaveDays;
/**姓名*/
private String name;
}
/**
* @program: cookbook
* @description: 请假责任链抽象处理类
* @author: Byron
* @create: 2019/07/11 09:34
*/
public class AbstractLeaveHandler {
/**直接主管审批处理的请假天数*/
protected int MIN = 1;
/**部门经理处理的请假天数*/
protected int MIDDLE = 3;
/**总经理处理的请假天数*/
protected int MAX = 30;
/**领导名称*/
protected String handlerName;
/**下一个处理节点(即更高级别的领导)*/
protected AbstractLeaveHandler nextHandler;
/**设置下一节点*/
protected void setNextHandler(AbstractLeaveHandler handler){
this.nextHandler = handler;
}
/**处理请假的请求,子类实现*/
protected void handlerRequest(LeaveRequest request){
}
}
/**
* @program: cookbook
* @description: 直接主管处理类
* @author: Byron
* @create: 2019/07/11 09:46
*/
public class DirectLeaderLeaveHandler extends AbstractLeaveHandler{
public DirectLeaderLeaveHandler(String name) {
this.handlerName = name;
}
@Override
protected void handlerRequest(LeaveRequest request) {
if(request.getLeaveDays() <= this.MIN){
System.out.println("直接主管:" + handlerName + ",已经处理;流程结束。");
return;
}
if(null != this.nextHandler){
this.nextHandler.handlerRequest(request);
}else{
System.out.println("审批拒绝!");
}
}
}
/**
* @program: cookbook
* @description: 部门经理处理类
* @author: Byron
* @create: 2019/07/11 09:48
*/
public class DeptManagerLeaveHandler extends AbstractLeaveHandler {
public DeptManagerLeaveHandler(String name) {
this.handlerName = name;
}
@Override
protected void handlerRequest(LeaveRequest request) {
if(request.getLeaveDays() >this.MIN && request.getLeaveDays() <= this.MIDDLE){
System.out.println("部门经理:" + handlerName + ",已经处理;流程结束。");
return;
}
if(null != this.nextHandler){
this.nextHandler.handlerRequest(request);
}else{
System.out.println("审批拒绝!");
}
}
}
/**
* @program: cookbook
* @description: 总经理处理类
* @author: Byron
* @create: 2019/07/11 09:49
*/
public class GManagerLeaveHandler extends AbstractLeaveHandler {
public GManagerLeaveHandler(String name) {
this.handlerName = name;
}
@Override
protected void handlerRequest(LeaveRequest request) {
if(request.getLeaveDays() > this.MIDDLE && request.getLeaveDays() <= this.MAX){
System.out.println("总经理:" + handlerName + ",已经处理;流程结束。");
return;
}
if(null != this.nextHandler){
this.nextHandler.handlerRequest(request);
}else{
System.out.println("审批拒绝!");
}
}
}
public class ResponsibilityTest {
public static void main(String[] args) {
LeaveRequest request = LeaveRequest.builder().leaveDays(20).name("小明").build();
AbstractLeaveHandler directLeaderLeaveHandler = new DirectLeaderLeaveHandler("县令");
DeptManagerLeaveHandler deptManagerLeaveHandler = new DeptManagerLeaveHandler("知府");
GManagerLeaveHandler gManagerLeaveHandler = new GManagerLeaveHandler("京兆尹");
directLeaderLeaveHandler.setNextHandler(deptManagerLeaveHandler);
deptManagerLeaveHandler.setNextHandler(gManagerLeaveHandler);
directLeaderLeaveHandler.handlerRequest(request);
}
}