一、描述:
把请求从链中的一个对象传到下一个对象,直到请求被响应为止。通过这种方式去除对象之间的耦合。避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。
角色:
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值。