再战设计模式(十二)之行为型-责任链模式

责任链模式(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 也是使用责任链模式

原文地址:https://www.cnblogs.com/bj-xiaodao/p/10861748.html