责任链模式(Chain of responsibility pattern)
概念
多套if else 的完美替代!!!不需要修改原代码!将能够处理同一类请求的对象连成一条链,所提交的请求沿着链传递,链上的对象逐个判断是否有能力处理该请求,如果能则处理,如果不能,则传递给下一个对象应用场景
1:打牌时,轮流出牌:
2:接力赛跑
3:公司公文审批
开发中场景
1:Java异常机制,一个try可以对应多个catch,当第一个catch不匹配类型,则自动跳到第二个catch
2:Javascript事件的冒泡和捕获机制,Java中事件处理采用的是观察者模式
3:Servlet开发中,过滤器的链式处理
4:Struts2中,拦截器的调用就是典型的责任链模式
案例(公司请假)
请假类(封装请假的基本信息)
/*
* 封装请假的基本信息
*/
public class HomeRequest {
private String name; //请假员工姓名
private int days; //请假天数
private String reasons; //请假原因
public HomeRequest(String name, int days, String reasons) {
super();
this.name = name;
this.days = days;
this.reasons = reasons;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getDays() {
return days;
}
public void setDays(int days) {
this.days = days;
}
public String getReasons() {
return reasons;
}
public void setReasons(String reasons) {
this.reasons = reasons;
}
}
抽象领导类
/*
* 抽象领导类
*/
public abstract class AbstractLeader {
protected String name;
protected AbstractLeader nextLeader; //责任链上的后继对象
public AbstractLeader(String name) {
super();
this.name = name;
}
//设定责任链上的后继对象
public void setNextLeader(AbstractLeader nextLeader) {
this.nextLeader = nextLeader;
}
/*
* 抽象方法,处理请求,核心方法
*/
public abstract void handleRequest(HomeRequest request);
}
第一审批人:主任(请假天数<3审批)
/*
* 主任审批
*/
public class Director extends AbstractLeader {
public Director(String name) {
super(name);
}
@Override
public void handleRequest(HomeRequest request) {
if(request.getDays() < 3){
System.out.println("员工:" + request.getName() + ",请假" + request.getDays() + "天!原因:" + request
.getReasons());
System.out.println("审批人:" + this.name + "审批通过");
}else{
if(this.nextLeader != null){
this.nextLeader.handleRequest(request);
}
}
}
}
第二审批人:经理(请假天数<15审批)
/*
* 经理审批
*/
public class Manager extends AbstractLeader {
public Manager(String name) {
super(name);
}
@Override
public void handleRequest(HomeRequest request) {
if(request.getDays() < 15){
System.out.println("员工:" + request.getName() + ",请假" + request.getDays() + "天!原因:" + request
.getReasons());
System.out.println("审批人:" + this.name + "审批通过");
}else{
if(this.nextLeader != null){
this.nextLeader.handleRequest(request);
}
}
}
}
第三审批人:总经理(请假天数<30审批)---最后一层审批人,做收尾工作,没有后续审批人了
/*
* 总经理审批
*/
public class GeneralManager extends AbstractLeader {
public GeneralManager(String name) {
super(name);
}
@Override
public void handleRequest(HomeRequest request) {
if(request.getDays() < 30){
System.out.println("员工:" + request.getName() + ",请假" + request.getDays() + "天!原因:" + request
.getReasons());
System.out.println("审批人:" + this.name + "审批通过");
}else{
System.out.println("不可以请假!"); //超过30天没有请假权限,没有下一个审批人
}
}
}
客户端测试
public class Client {
public static void main(String[] args) {
AbstractLeader first = new Director("卡拉格");
AbstractLeader second = new Manager("拉拉纳");
AbstractLeader third = new GeneralManager("杰拉德");
//设置后继对象
first.setNextLeader(second);
second.setNextLeader(third);
//请假员工
HomeRequest person = new HomeRequest("斯图里奇",15, "大腿拉伤!!");
first.handleRequest(person);
}
}
console:
员工:斯图里奇,请假15天!原因:大腿拉伤!!
审批人:杰拉德审批通过