#一、概述
- 设计模式
- 创建型模式:关注对象的创建过程
- 结构型模式:关注对象和类的组织
- 行为型模式:关注系统中对象之间的相互交互,研究系统在运行时对象之间的相互通信和协作,进一步明确对象的责任,共11种模式
责任链模式(
chain of responsibility
)
定义:将能够处理同一类请求的对象练成一条链,所提交的请求沿着链传递,链上的对象逐个判断是否有能力处理该请求,如果能则处理,否则,传递给链上的下一个对象。-
场景:
- 打牌时,轮流出牌
- 接力赛跑
- 大学中,奖学金审批
- 公司中,公文审批
二、实例:请假条审批流程案例
LeaveRequest.java
package cn.itcast.day243.chainOfRespon;
//请假条:封装请求的基本信息
public class LeaveRequest {
private String empName;// 请假人
private int leaveDays;// 请假天数
private String reason;// 请假原因
public LeaveRequest() {
}
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;
}
}
说明:这就相当于一个任务类。
Leader.java
package cn.itcast.day243.chainOfRespon;
//审批人:抽象类
public abstract class Leader {
// 因为只是给子类使用,所以这里使用protected
protected String name;// 领导名字
protected Leader nextLeader;// 领导的上一级领导
public Leader() {
}
public Leader(String name) {
this.name = name;
}
public void setNextLeader(Leader nextLeader) {
this.nextLeader = nextLeader;
}
public abstract void handleRequest(LeaveRequest request);//处理请求业务的核心方法
}
说明:这是一个处理器接口,因为每个审批对象有很多类似的地方。
Director.java
package cn.itcast.day243.chainOfRespon;
//主任
public class Director extends Leader {
public Director(String name) {
super(name);
}
public void handleRequest(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.handleRequest(request);
}
}
}
}
Manager.java
package cn.itcast.day243.chainOfRespon;
//经理
public class Manager extends Leader {
public Manager(String name) {
super(name);
}
public void handleRequest(LeaveRequest request) {
if (request.getLeaveDays() < 10) {
System.out.println("经理处理员工" + request.getEmpName() + "请假"
+ request.getLeaveDays() + "天,理由是:" + request.getReason());
System.out.println("经理" + this.name + "审批通过");
} else {
if (this.nextLeader != null) {
this.nextLeader.handleRequest(request);
}
}
}
}
GeneralManager.java
package cn.itcast.day243.chainOfRespon;
//总经理
public class GeneralManager extends Leader {
public GeneralManager(String name) {
super(name);
}
public void handleRequest(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() + "天,理由是:" + request.getReason());
System.out.println("总经理" + this.name + "审批不通过");
}
}
}
说明:这是三个具体的处理器,分别处理不同等级但同类的事件。
Client.java
package cn.itcast.day243.chainOfRespon;
public class Client {
public static void main(String[] args) {
Leader l1 = new Director("张三");
Leader l2 = new Manager("李四");
Leader l3 = new GeneralManager("王五");
//组织责任链对象的关系
l1.setNextLeader(l2);
l2.setNextLeader(l3);
//处理请假操作
LeaveRequest request = new LeaveRequest("Tom", 1, "回英国老家探亲");
l1.handleRequest(request);
}
}
说明:可以看到各个具体的处理器的关系是我们在使用的时候才确定的,如果我们需要在中间添加其他的处理器类可以很方便的添加,只需要在使用的时候调整各个处理器的关系即可。
三、两种责任链方式
- 链表方式定义职责链(上面的案例)
- 非链表方式实现职责链
通过集合、数组生成职责链更加使用。实际上,很多项目中,每个具体Handler
并不是由开发团队定义的,而是项目上线后由外部单位追加的,所以使用链表方式定义COR
链就很困难。
四、开发中常见的场景
-
java
中,异常机制就是一种责任链模式。一个try
可以对应多个catch
,当第一个catch
不匹配类型,则自动跳到第二个catch
-
js
中,事件的冒泡和捕获机制。java
中,事件处理采用观察者模式 -
servlet
中,过滤器的链式处理 -
struts2
中,拦截器的调用也是典型的责任链模式