定义
使多个对象都有机会处理请求,从而避免了请求的发送者和接收者致敬的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。
使用场景
- 多个对象可以处理同一请求,但是具体有哪个来处理则在运行时动态决定
- 在请求处理者不明确的情况下向多个对象中的一个提交请求
- 需要动态指定一组对象处理请求
- 代码中存在多个if-else语句的情况下,此时可以考虑使用责任链模式来对代码进行重构。
结构
-
AbstractHandler
抽象处理角色,声明了处理对象处理请求的方法,并在其中保存一个对下一个处理节点AbstractHandler的引用
-
AbstractRequest
抽象请求者或者具体请求者,根据不同需求可以选择性采取策略
简单实现
模拟请假流程
public abstract class Leader {
/**
* 下一节点上的处理者对象
*/
protected Leader nextHandler;
/**
* 处理请求
*
* @param request 请求对象
*/
public final void handlerRequest(LeaveRequest request) {
if (request.getDay() <= limit()) {
handle(request);
} else {
if (null != nextHandler) {
nextHandler.handlerRequest(request);
}
}
}
/**
* 请求处理
*
* @param request 请求条件
*/
protected abstract void handle(LeaveRequest request);
/**
* 有权审批的最大天数
*
* @return 最大天数
*/
public abstract int limit();
}
Leader类充当AbstractHandler的角色,负责主要的逻辑实现;责任转发的逻辑交由handlerRequest()实现,声明了一个获取限制条件的limit()抽象方法
public class LeaveRequest {
private String name;
private int day;
public LeaveRequest(String name, int day) {
this.name = name;
this.day = day;
}
//get set 省略
...
}
LeaveRequest为请求者的信息,这里为了简单,没有使用抽象类
public class TeamLeader extends Leader {
private String name;
public TeamLeader(String name) {
this.name = name;
}
@Override protected void handle(LeaveRequest request) {
System.out.println(name + "审批员工" + request.getName() + " 的请假条,请假天数为" + request.getDay() + "天");
}
@Override public int limit() {
return 3;
}
}
public class Manager extends Leader {
private String name;
public Manager(String name) {
this.name = name;
}
@Override protected void handle(LeaveRequest request) {
System.out.println(name + "审批员工" + request.getName() + " 的请假条,请假天数为" + request.getDay() + "天");
}
@Override public int limit() {
return 10;
}
}
public class Director extends Leader {
private String name;
public Director(String name) {
this.name = name;
}
@Override protected void handle(LeaveRequest request) {
System.out.println(name + "审批员工" + request.getName() + " 的请假条,请假天数为" + request.getDay() + "天");
}
@Override public int limit() {
return 15;
}
}
public class Boss extends Leader {
private String name;
public Boss(String name) {
this.name = name;
}
@Override protected void handle(LeaveRequest request) {
System.out.println(name + "审批员工 " + request.getName() + " 的请假条,请假天数为" + request.getDay() + "天");
}
@Override public int limit() {
return Integer.MAX_VALUE;
}
}
具体的几个处理者对象,各自负责各自功能的实现
public class Test {
public static void main(String[] args) {
// 处理者对象
Leader handler1 = new TeamLeader("沙僧");
Leader handler2 = new Manager("八戒");
Leader handler3 = new Director("悟空");
Leader handler4 = new Boss(" 唐僧");
// 请求者对象
LeaveRequest request1 = new LeaveRequest("张三", 2);
LeaveRequest request2 = new LeaveRequest("李四", 5);
LeaveRequest request3 = new LeaveRequest("王五", 11);
LeaveRequest request4 = new LeaveRequest("赵六", 18);
LeaveRequest request5 = new LeaveRequest("赵六", 30);
//设置责任节点链
handler1.nextHandler = handler2;
handler2.nextHandler = handler3;
handler3.nextHandler = handler4;
System.out.println("---------request1---------------");
handler1.handlerRequest(request1);
System.out.println("----------request2--------------");
handler1.handlerRequest(request2);
System.out.println("-----------request3-------------");
handler1.handlerRequest(request3);
System.out.println("-----------request4-------------");
handler1.handlerRequest(request4);
System.out.println("-----------request5-------------");
handler1.handlerRequest(request5);
System.out.println("-----------request1-------------");
handler3.handlerRequest(request1);
System.out.println("-----------request4-------------");
handler3.handlerRequest(request4);
}
}
测试类及结果
---------request1---------------
沙僧审批员工张三 的请假条,请假天数为2天
----------request2--------------
八戒审批员工李四 的请假条,请假天数为5天
-----------request3-------------
悟空审批员工王五 的请假条,请假天数为11天
-----------request4-------------
唐僧审批员工 赵六 的请假条,请假天数为18天
-----------request5-------------
唐僧审批员工 赵六 的请假条,请假天数为30天
-----------request1-------------
悟空审批员工张三 的请假条,请假天数为2天
-----------request4-------------
唐僧审批员工 赵六 的请假条,请假天数为18天
思考
责任链模式理解起来比较简单,核心的思想就是在AbstractHandler中保留一个AbstractHandler的引用来进行处理
责任链模式的主要优点在于可以降低系统耦合度,简化对象的相互连接,同时增强给对象指派职责的灵活性,增加新的处理类也很方便
对于比较长的责任链,请求的处理可能涉及多个对象,对性能可能会有一定影响
不能保证请求一定被接收,下游的请求无法传递给上游处理