设计模式:责任链模式(ChainOfResponsibility)

什么是责任链模式

责任链模式:将能够处理同一类请求的对象连成一条链,所提交的请求沿着链传递,链上的对象逐个判断是否有能力处理该请求,如果能则处理,如果不能则传递给链上的下一个对象。

链表方式定义责任链

如果try,catch一样,先判断第一个catch是否符合处理异常,如果不符合则交给下一个catch,依此类推找到可以处理的catch.

非链表方式实现责任链

通过集合,数组生成责任链,更加的实用.实际上,很多项目中,每个具体的Handler并不是由团队开发定义的,而是项目上线后由外部单位追加的,所以使用链表方式定义COR链就很困难.

添加新的处理对象

由于责任链的创建完全符合在客户端,因此新增新的具体处理者对原有类库没有任何影响.只需添加新的类,然后在客户端调用时添加即可.

经典案例

案例: 我们可以在请假处理流程中,增加新的“副总经理”角色,审批大于等于 * 10天,小于20天的请假。审批流程变为: ① 如果请假天数小于3天,主任审批 。② 如果请假天数大于等于3天,小于10天,经理审批 。③ 大于等于10天,小于20天的请假,副总经理审批 。 ④ 如果大于等于20天,小于30天,总经理审批 。⑤ 如果大于等于30天,提示拒绝

请假的基本信息:

/**
 * 
 * @author 233admincol
 *@description 封装请假的基本信息
 */
public class LeaveRequest {

	private String empName;
    private int leaveDays;
    private String reason;
 
    public LeaveRequest(String empName, int leaveDays, String reason) {
        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;
    }
}

领导的抽象类

public abstract class Leader {
protected String name;
protected Leader nextLeader;//责任链上的后继对象
public Leader(String name) {
	this.name=name;
}
//设定责任链上的后继对象
public void setNextLeader(Leader nextLeader) {
	this.nextLeader=nextLeader;
}
//处理请求的核心的业务方法
public abstract void handRequest(LeaveRequest request);
}

经理

public class Manager extends Leader{
	public Manager(String name) {
        super(name);
    }
 
    // 责任链操作
    @Override
    public void handRequest(LeaveRequest request) {
        if(request.getLeaveDays() >= 3 && request.getLeaveDays() < 10) {
            System.out.println("员工: " + request.getEmpName() + "请假,天数:" + request.getLeaveDays() + ",理由: " + request.getReason());
            System.out.println("经理: " + this.name + "审批通过...");
        }else {
            // 如果当前责任链无法处理会转向下家责任链
            if(this.nextLeader != null) {
                this.nextLeader.handRequest(request);
            }
        }
    }
}

副总经理

public class ViceGeneralManager extends Leader{
	 public ViceGeneralManager(String name) {
	        super(name);
	    }
	 
	    @Override
	    public void handRequest(LeaveRequest request) {
	        if(request.getLeaveDays() < 20) {
	            System.out.println("员工: " + request.getEmpName() + "请假,天数:" + request.getLeaveDays() + ",理由: " + request.getReason());
	            System.out.println("副总经理: " + this.name + "审批通过...");
	        }else {
	            System.out.println(request.getEmpName() + "请假: " + request.getLeaveDays() + "天,审批不通过...");
	        }
	    }

}

总经理

public class GeneralManager extends Leader{
	public GeneralManager(String name) {
        super(name);
    }
 
    @Override
    public void handRequest(LeaveRequest request) {
        if(request.getLeaveDays() < 30) {
            System.out.println("员工: " + request.getEmpName() + "请假,天数:" + request.getLeaveDays() + ",理由: " + request.getReason());
            System.out.println("总经理: " + this.name + "审批通过...");
        }else {
            System.out.println(request.getEmpName() + "请假: " + request.getLeaveDays() + "天,审批不通过...");
        }
    }
}

主任

public class Director extends Leader{
	 public Director(String name) {
	        super(name);
	    }
	 
	    @Override
	    public void handRequest(LeaveRequest request) {
	        if(request.getLeaveDays() < 3) {
	            System.out.println("员工: " + request.getEmpName() + "请假,天数:" + request.getLeaveDays() + ",理由: " + request.getReason());
	            System.out.println("主任: " + this.name + "审批通过...");
	        }else {
	            if(this.nextLeader != null) {
	                this.nextLeader.handRequest(request);
	            }
	        }
	    }
}

测试代码

public class Test {
	 public static void main(String[] args) {
	        Leader a = new Director("张三");  // 主任
	        Leader b = new Manager("李四");   // 经理
	        Leader c = new ViceGeneralManager("王五");    // 副总经理
	        Leader d = new GeneralManager("马六");    // 总经理
	 
	        // 组织责任链对象的关系
	        a.setNextLeader(b); // 主任的上级领导是经理
	        b.setNextLeader(c); // 经理的上级领导是副总经理
	        c.setNextLeader(d); // 副总经理的上级领导是总经理
	 
	        // 开始请假操作
	        LeaveRequest tom = new LeaveRequest("Tom",19,"回英国探亲!");
	        a.handRequest(tom);
	    }

}

在这里插入图片描述

开发中的常见场景

  • Java中,异常机制就是一种责任链模式。一个try可以对应多个catch,当第一个catch不匹配类型,则自动跳到第二个catch.
  • Javascript语言中,事件的冒泡和捕获机制。Java语言中,事件的处理采用观察者模式。
  • Servlet开发中,过滤器的链式处理
  • Struts2中,拦截器的调用也是典型的责任链模式
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章