责任链模式(chain of responsibility)
定义:
将能够处理同一类请求的对象连成一条链,所提交的请求沿着链传递,链上的对象逐个判断是否有能力处理该请求,如果能则处理,如果不能则传给链上的下一个对象.
使用责任链模式,可以将请求方和处理方的关系弱化,让各方都可以成为独立复用的组件.
场景:
- 打牌时,乱流出牌
- 接力赛跑
- 大学中,奖学金的审批
- 公司中,请假流程,报销流程的审批
我在这里做一个例子:
公司的请教流程审批过程,如果小于3天 主任就可以审批通过 如果3天以上 10天以下 经理审批 如果10天以上,30天以下就是总经理审批 如果大于30天就是不能审批..
类图:
角色:
具体的请求类:leaveRequest
handler(处理者) 一般是一个抽象类,持有下一个处理者 并且有子类才实现 由leaveHandlerChain
concreteHandler 由direcorChian mangeChain generalMangerChain nosupportChain 来实现
代码如下:
/** * @Created by xiaodao * 具体要处理的trouble 问题 * */ public class LeaveRequest { private String name; private String reason; private int leaveDays; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getReason() { return reason; } public void setReason(String reason) { this.reason = reason; } public int getLeaveDays() { return leaveDays; } public void setLeaveDays(int leaveDays) { this.leaveDays = leaveDays; } public LeaveRequest(String name, String reason, int leaveDays) { this.name = name; this.reason = reason; this.leaveDays = leaveDays; } } /** * @Created by xiaodao
处理者.. * */ public abstract class LeaderHandlerChain { protected String name; public LeaderHandlerChain(String name) { this.name = name; } public void setNextLeader(LeaderHandlerChain nextLeader) { this.nextLeader = nextLeader; } protected LeaderHandlerChain nextLeader; //责任链下一个要处理的领导 /** * 处理请求的核心方法 * @param request */ public abstract void handlerRequest(LeaveRequest request); } /**
* 主任的处理链上的实现
* @Created by xiaodao */ public class DirectorChain extends LeaderHandlerChain { public DirectorChain(String name) { super(name); } @Override public void handlerRequest(LeaveRequest request) { if(request.getLeaveDays() <=3){ System.out.println("员工 "+ name +" request leave days is "+ request.getLeaveDays() +"天 请假原因 is "+ request.getReason()); System.out.println("主任 : "+ this.name +" 审批通过"); }else{ if(this.nextLeader !=null){ this.nextLeader.handlerRequest(request); } } } } /** * @Created by xiaodao */ public class ManageChain extends LeaderHandlerChain { public ManageChain(String name) { super(name); } @Override public void handlerRequest(LeaveRequest request) { if(request.getLeaveDays() <=10){ System.out.println("员工 "+ name +" request leave days is "+ request.getLeaveDays() +"天 请假原因 is "+ request.getReason()); System.out.println("经理: "+ this.name +" approved"); }else{ if(this.nextLeader !=null){ this.nextLeader.handlerRequest(request); } } } } /** * @Created by xiaodao * 总经理审批 */ public class GeneralManageChain extends LeaderHandlerChain { public GeneralManageChain(String name) { super(name); } @Override public void handlerRequest(LeaveRequest request) { if(request.getLeaveDays() <=30){ System.out.println("员工 "+ name +" request leave days is "+ request.getLeaveDays() +"天 请假原因 is "+ request.getReason()); System.out.println("GeneralManageChain " +this.name +" approved"); }else{ if(this.nextLeader !=null){ this.nextLeader.handlerRequest(request); } } } } /** * @Created by xiaodao */ public class NoSupportLeaveChain extends LeaderHandlerChain { public NoSupportLeaveChain(String name) { super(name); } @Override public void handlerRequest(LeaveRequest request) { System.out.println("莫非...."+request.getName()+"不想干了? 居然 请假 "+ request.getLeaveDays()+"天"); } } /** * @Created by xiaodao */ public class Client { public static void main(String[] args) { LeaderHandlerChain directorChain = new DirectorChain("张三"); LeaderHandlerChain manger = new ManageChain("李四"); LeaderHandlerChain generalManage = new GeneralManageChain("王五"); LeaderHandlerChain auto = new NoSupportLeaveChain("机器"); //组织链式关系 directorChain.setNextLeader(manger); manger.setNextLeader(generalManage); generalManage.setNextLeader(auto); LeaveRequest emt = new LeaveRequest("小刀","想请假回去学习",1); directorChain.handlerRequest(emt); } }
如果我传入1天那么就是:主任审批
员工 张三 request leave days is 1天 请假原因 is 想请假回去学习
主任 : 张三 审批通过
如果我想请假10天:那就是经理审批
员工 李四 request leave days is 10天 请假原因 is 想请假回去学习
经理: 李四 approved
如果我想请假30天:那就是 总经理审批
员工 王五 request leave days is 30天 请假原因 is 想请假回去学习
GeneralManageChain 王五 approved
如果我想请假的天数超出最大的话,有一个模式拒绝的处理类.
莫非....小刀不想干了? 居然 请假 31天
总结
1.可以解决程序中的扩展问题.如果我们需要添加一个中间的情况,那么只需要在责任链中添加一个就行,不用去修改原有的代码
2.在client上组成的链式结构,我们可以在项目开发中定义好,动态的去显示,比如到缓存里.
项目中哪里使用?
1.异常类中的try catch 就是使用责任链模式
2.servlet的chain 也是使用责任链模式