Spring 设计模式之责任链模式

Spring 设计模式之责任链模式

责任链模式

责任链模式(Chain of Responsibility)是一种行为设计模式,它允许你将请求沿着处理者链进行传递。

每个处理者可以对请求进行处理,也可以将请求传递给链中的下一个处理者。这个模式使得你可以在不修改对象间连接的情况下,动态地增加或删除责任。

用到的场景

强调链条传递,每一个环节都处理一下

1.入参校验

  • 多级校验:将校验逻辑拆分为多个独立的处理器,每个处理器负责一种或多种校验规则。这些处理器形成一条链式调用,请求在处理器链上传递,如果校验条件不通过,则处理器不再向下传递请求,直接返回错误信息;若所有的处理器都通过检验,则继续执行后续的业务逻辑。

  • 可复用性:校验处理器可以独立开发和测试,便于在不同场景下复用。
    2. 权限校验

  • 多级权限检查:将权限校验逻辑拆分为多个处理器,每个处理器负责一种或多种权限检查规则。这些处理器按顺序组成一条链,请求(如API调用或页面访问)在链上传递,每个处理器根据自己的职责检查请求是否满足相应的权限要求。

  • 细粒度控制:通过多个处理器可以实现细粒度的权限控制,比如角色检查、资源权限检查、操作权限检查等。

  • 动态调整:权限处理器可以动态地添加、删除或修改,以适应不同的安全需求或用户角色变化。
    3. 工作流处理

  • 任务分解:将复杂的工作流程分解为多个独立的处理步骤,每个步骤由一个或多个处理器负责。

  • 顺序执行:处理器按照预设的顺序依次执行,每个处理器处理完自己的任务后,将请求传递给下一个处理器。

  • 动态扩展:通过配置或编程方式动态地添加、删除或修改处理器,以适应不同的工作流程需求。
    4. 事件处理

  • 事件监听:在Spring框架中,可以使用责任链模式来监听和处理事件。每个处理器都可以注册为事件监听器,当事件发生时,按照注册的顺序依次调用处理器的处理方法。

  • 事件分发:事件分发器负责将事件对象传递给链中的第一个处理器,处理器根据事件类型和自己的职责决定是否处理该事件,或者将事件传递给下一个处理器。
    5. 异常处理

  • 异常捕获:在业务逻辑执行过程中,可能会遇到各种异常情况。使用责任链模式可以将异常处理逻辑拆分为多个处理器,每个处理器负责捕获和处理一种或多种异常类型。

  • 异常传递:当一个处理器无法处理当前异常时,可以将异常对象传递给下一个处理器,直到找到合适的处理器为止。
    6. 请求处理

  • 请求分发:在Web应用程序中,请求处理器可以形成一个责任链,用于处理不同类型的HTTP请求。每个处理器都可以根据自己的职责决定是否处理该请求,或者将请求传递给下一个处理器。

  • 请求过滤:在请求到达控制器之前,可以使用责任链模式对请求进行过滤和预处理,比如身份验证、参数校验、日志记录等。

java举例

java 复制代码
package com.example.customer.controller;

// 定义一个处理请求的接口
interface Handler {
    // 设置下一个处理者
    void setNextHandler(Handler nextHandler);

    // 处理请求的方法
    void handleRequest(int days);
}

// 具体的处理者类,比如部门经理,实现Handler接口
class DepartmentManager implements Handler {
    private Handler nextHandler;

    @Override
    public void setNextHandler(Handler nextHandler) {
        this.nextHandler = nextHandler;
    }

    @Override
    public void handleRequest(int days) {
        if (days <= 5) {
            System.out.println("部门经理批准了请假 " + days + " 天。");
        } else {
            if (nextHandler != null) {
                nextHandler.handleRequest(days);
            } else {
                System.out.println("没有合适的领导可以批准请假 " + days + " 天。");
            }
        }
    }
}

// 具体的处理者类,比如总经理,实现Handler接口
class GeneralManager implements Handler {
    private Handler nextHandler;

    @Override
    public void setNextHandler(Handler nextHandler) {
        this.nextHandler = nextHandler;
    }

    @Override
    public void handleRequest(int days) {
        if (days <= 10) {
            System.out.println("总经理批准了请假 " + days + " 天。");
        } else {
            if (nextHandler != null) {
                nextHandler.handleRequest(days);
            } else {
                System.out.println("没有合适的领导可以批准请假 " + days + " 天。");
            }
        }
    }
}

// 具体的处理者类,比如董事长,实现Handler接口
class Chairman implements Handler {
    @Override
    public void setNextHandler(Handler nextHandler) {
        // 董事长作为最高级领导,不需要设置下一个处理者
        // 这里可以不做任何操作,或者抛出一个异常表示不应该调用此方法
        // 但为了符合接口定义,我们还是保留这个方法体为空
    }

    @Override
    public void handleRequest(int days) {
        if (days > 10) {
            System.out.println("董事长批准了请假 " + days + " 天。");
        } else {
            // 理论上董事长不会处理小于等于10天的请假,但这里为了完整性加上
            System.out.println("董事长不处理小于等于10天的请假请求。");
        }
        // 注意:董事长没有下一个处理者,所以不需要调用nextHandler.handleRequest(days);
    }
    
}

public class ChainOfResponsibilityDemo {
    public static void main(String[] args) {
        // 创建处理者对象-部门经理
        Handler departmentManager = new DepartmentManager();
        // 创建处理者对象-总经理
        Handler generalManager = new GeneralManager();
        // 创建处理者对象-董事长
        Handler chairman = new Chairman();

        //设置部门经理下一个处理者总经理
        departmentManager.setNextHandler(generalManager);
        //设置总经理下一个处理者董事长
        generalManager.setNextHandler(chairman);

        // 提交请假请求
        departmentManager.handleRequest(3);  // 该假条是部门经理进行批准的
        departmentManager.handleRequest(7);  // 该假条是总经理进行批准的
        departmentManager.handleRequest(11);  // 该假条是总经理进行批准的
    }
}

输出

java 复制代码
部门经理批准了请假 3 天。
总经理批准了请假 7 天。
董事长批准了请假 11 天。
相关推荐
蜡笔小马8 小时前
07.C++设计模式-组合模式
c++·设计模式·组合模式
Volunteer Technology8 小时前
SpringAI Chat Client (四)
人工智能·spring
ShiJiuD6668889999 小时前
springboot基础篇
java·spring boot·spring
敲敲千反田9 小时前
Spring AI
java·人工智能·spring
拽着尾巴的鱼儿9 小时前
spring 动态代理
java·后端·spring
云烟成雨TD10 小时前
Spring AI Alibaba 1.x 系列【52】Interrupts 中断机制:案例演示
java·人工智能·spring
云烟成雨TD11 小时前
Spring AI Alibaba 1.x 系列【51】Graph 整体运行全流程
java·人工智能·spring
_waylau12 小时前
“Java+AI全栈工程师”问答02:Spring Boot 自动配置原理
java·开发语言·spring boot·后端·spring
雪度娃娃12 小时前
结构型设计模式——享元模式
c++·设计模式·享元模式
Ting-yu12 小时前
SpringCloud快速入门(4)---- nacos安装与使用
java·spring·spring cloud