一、描述:
把请求从链中的一个对象传到下一个对象,直到请求被响应为止。通过这种方式去除对象之间的耦合。避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。
角色:
1.抽象处理者角色:定义处理的抽象方法,可以设置具体处理者
2.具体处理者角色:实现抽象处理方法。
(1)每个角色可处理它负责的请求,也可访问它的后继者。如果可处理该请求,就处理之。否则将该请求转发给它的后继者。
3.请求角色:调用处理者。
类图:
二、优点
1.降低耦合度。
2.增强了给对象指派职责的灵活性。
三、缺点
1.不保证被接收。既然一个请求没有明确的接收者,那么就不能保证它一定会被处理,该请求可能一直到链的末端都得不到处理。
四、适用场景
1.有多个对象可以处理同一个请求,哪个对象处理该请求运行时刻自动确定。
2.在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
3.可处理一个请求的对象集合应被动态指定。
五、举例
以“员工请假”为例。请假天数不同,审核人员不同。流程图如下:
代码:
1.员工
@Data
public class Employee {
/**
* 姓名
*/
private String name;
/**
* 请假天数
*/
private Integer leaveDay;
}
2.抽象处理类
public abstract class AbstractHandler {
public AbstractHandler handler;
/**
* 设置下个处理类
*
* @param handler
*/
public void setNext(AbstractHandler handler) {
this.handler = handler;
}
/**
* 处理请假天数
*/
public abstract void dealLeave(Employee employee);
}
3.组长审核类
public class GroupLeaderHandler extends AbstractHandler {
@Override
public void dealLeave(Employee employee) {
if (employee.getLeaveDay() <= 2) {
System.out.println("组长已审核");
} else {
handler.dealLeave(employee);
}
}
}
4.部门经理审核类
public class DepartmentManagerHandler extends AbstractHandler {
@Override
public void dealLeave(Employee employee) {
if (employee.getLeaveDay() <= 3) {
System.out.println("部门经理已审核");
} else {
handler.dealLeave(employee);
}
}
}
5.CTO处理类
public class CTOHandler extends AbstractHandler {
@Override
public void dealLeave(Employee employee) {
if (employee.getLeaveDay() > 3) {
System.out.println("CTO已审核");
} else {
System.out.println("审核天数不在审核范围内");
}
}
}
6.模拟请假
public class Client {
public static void main(String[] args) {
Employee employee = new Employee();
employee.setName("张三");
employee.setLeaveDay(5);
GroupLeaderHandler leaderHandler = new GroupLeaderHandler();
DepartmentManagerHandler departmentManagerHandler = new DepartmentManagerHandler();
CTOHandler ctoHandler = new CTOHandler();
leaderHandler.setNext(departmentManagerHandler);
departmentManagerHandler.setNext(ctoHandler);
leaderHandler.dealLeave(employee);
}
}
效果:
在具体工作中,在验证访客信息的时候,网关系统用到了职责链模式。访客有公司内部系统,外部访问人员等,针对公司内部系统,需要一个固定的凭证,就可以进入系统,但是对于外部访问人员,需要动态校验token值。