Spring 设计模式之责任链模式

news/2024/11/6 11:01:57 标签: spring, 设计模式, 责任链模式

Spring 设计模式责任链模式

责任链模式

责任链模式(Chain of Responsibility)是一种行为设计模式,它允许你将请求沿着处理者链进行传递。
每个处理者可以对请求进行处理,也可以将请求传递给链中的下一个处理者。这个模式使得你可以在不修改对象间连接的情况下,动态地增加或删除责任。

用到的场景

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

1.入参校验

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

2. 权限校验

  • 多级权限检查:将权限校验逻辑拆分为多个处理器,每个处理器负责一种或多种权限检查规则。这些处理器按顺序组成一条链,请求(如API调用或页面访问)在链上传递,每个处理器根据自己的职责检查请求是否满足相应的权限要求。
  • 细粒度控制:通过多个处理器可以实现细粒度的权限控制,比如角色检查、资源权限检查、操作权限检查等。
  • 动态调整:权限处理器可以动态地添加、删除或修改,以适应不同的安全需求或用户角色变化。

3. 工作流处理

  • 任务分解:将复杂的工作流程分解为多个独立的处理步骤,每个步骤由一个或多个处理器负责。
  • 顺序执行:处理器按照预设的顺序依次执行,每个处理器处理完自己的任务后,将请求传递给下一个处理器。
  • 动态扩展:通过配置或编程方式动态地添加、删除或修改处理器,以适应不同的工作流程需求。

4. 事件处理

  • 事件监听:在Spring框架中,可以使用责任链模式来监听和处理事件。每个处理器都可以注册为事件监听器,当事件发生时,按照注册的顺序依次调用处理器的处理方法。
  • 事件分发:事件分发器负责将事件对象传递给链中的第一个处理器,处理器根据事件类型和自己的职责决定是否处理该事件,或者将事件传递给下一个处理器。

5. 异常处理

  • 异常捕获:在业务逻辑执行过程中,可能会遇到各种异常情况。使用责任链模式可以将异常处理逻辑拆分为多个处理器,每个处理器负责捕获和处理一种或多种异常类型。
  • 异常传递:当一个处理器无法处理当前异常时,可以将异常对象传递给下一个处理器,直到找到合适的处理器为止。

6. 请求处理

  • 请求分发:在Web应用程序中,请求处理器可以形成一个责任链,用于处理不同类型的HTTP请求。每个处理器都可以根据自己的职责决定是否处理该请求,或者将请求传递给下一个处理器。
  • 请求过滤:在请求到达控制器之前,可以使用责任链模式对请求进行过滤和预处理,比如身份验证、参数校验、日志记录等。

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);  // 该假条是总经理进行批准的
    }
}

输出

部门经理批准了请假 3 天。
总经理批准了请假 7 天。
董事长批准了请假 11 天。

http://www.niftyadmin.cn/n/5740801.html

相关文章

学习python中的pandas有没有好的教程推荐?

看到Pandas我可就不困了&#xff0c;这是我用的最多的工具。 Pandas作为Python数科领域最顶级的库之一&#xff0c;就像excel之于office&#xff0c;是处理数据必备工具。 Pandas的学习教程自然不会少&#xff0c;在Github上搜索Pandas&#xff0c;会出现超过6万个项目&#…

Node.js——fs模块-文件夹操作

1、借助Node.js的能力&#xff0c;我们可以对文件夹进行创建、读取、删除等操作 2、方法 方法 说明 mkdir/mkdirSync 创建文件夹 readdir/readdirSync 读取文件夹 rmdir/rmdirSync 删除文件夹 3、语法 其余的方法语法类似 本文的分享到此结束&#xff0c;欢迎大家评论区…

VMWARE ESXI VMFS阵列故障 服务器数据恢复

1&#xff1a;河南用户一台DELL R740 3块2.4T硬盘组的RAID5&#xff0c;早期坏了一个盘没有及时更换&#xff0c;这次又坏了一个&#xff0c;导致整组RAID5处于数据丢失的状态&#xff0c; 2&#xff1a;该服务器装的是VMware ESXI 6.7&#xff0c;用户把3块硬盘寄过来进行数据…

Chromium Mojo(IPC)进程通信演示 c++(4)

122版本自带的mojom通信例子仅供学习参考&#xff1a; codelabs\mojo_examples\01-multi-process 其余定义参考文章&#xff1a; Chromium Mojo(IPC)进程通信演示 c&#xff08;2&#xff09;-CSDN博客 01-mojo-browser.exe 与 01mojo-renderer.exe进程通信完整例子。 一、…

常用的c++新特性--> day02

可调用对象 案例 #include <iostream> #include <string> #include <vector> using namespace std;using funcptr void(*)(int, string);int print(int a, double b) {cout << a << ", " << b << endl;return 0; } // …

unity3d————屏幕坐标,GUI坐标,世界坐标的基础注意点

在Unity3D中&#xff0c;GUI控件的起始坐标与屏幕坐标的起始点并不完全相同&#xff0c;具体说明如下&#xff1a; GUI控件的起始坐标 绘制GUI界面时使用的坐标以屏幕的左上角为(0,0)点&#xff0c;右下角为(Screen.width, Screen.Height)。不过&#xff0c;对于GUI控件的具体…

无人机之姿态融合算法篇

无人机的姿态融合算法是无人机飞行控制中的核心技术之一&#xff0c;它通过将来自不同传感器的数据进行融合&#xff0c;以实现更加精确、可靠的姿态检测。 一、传感器选择与数据预处理 无人机姿态融合算法通常依赖于多种传感器&#xff0c;包括加速度计、陀螺仪、磁力计等。这…

[Web安全 网络安全]-DoS(拒绝服务攻击)和DDoS(分布式拒绝服务攻击)

文章目录&#xff1a; 一&#xff1a;前言 1.DoS攻击 2.DDoS攻击 3.DoS攻击和DoS攻击的异同 4.原理 5.攻击流程 6.分类 7.影响 8.防御 9.工具 二&#xff1a;攻击方式 一&#xff1a;前言 1.DoS攻击 DoS攻击&#xff0c;即拒绝服务攻击故意的攻击网络协议实现的缺…