学习记录-责任链模式验证参数

news2025/1/16 19:50:34

学习记录-责任链模式验证参数

1.什么是责任链模式

责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,它允许将请求沿着一个处理链传递,直到链中的某个对象处理它。这样,发送者无需知道哪个对象将处理请求,所有的处理对象都可以尝试处理请求或将请求传递给链上的下一个对象。

img

2.使用责任链模式的好处

职责单一: 责任链模式可以将每个验证逻辑封装到一个独立的处理器中,每个处理器负责单一的验证职责,符合单一职责原则。

可扩展性: 增加新的验证逻辑时,只需添加新的处理器,而不需要修改现有的代码。

清晰的流程: 将所有验证逻辑组织在一起,使得代码结构更加清晰,易于理解。

3.实现

3.1定义责任链抽象接口

public interface AbstractChainHandler<T> extends Ordered {/**
     * 执行责任链逻辑
     *
     * @param requestParam 责任链执行入参
     */
    void handler(T requestParam);/**
     * @return 责任链组件标识
     */
    String mark();
}

3.2创建责任链模式上下文容器

@Component
public final class ChainContext<T> implements ApplicationContextAware, CommandLineRunner {/**
     * 应用上下文,我们这里通过 Spring IOC 获取 Bean 实例
     */
    private ApplicationContext applicationContext;
    /**
     * 保存商家后管责任链实现类
     * <p>
     * Key:{@link MerchantAdminAbstractChainHandler#mark()}
     * Val:{@link MerchantAdminAbstractChainHandler} 一组责任链实现 Spring Bean 集合
     * <p>
     * 比如有一个优惠券模板创建责任链,实例如下:
     * Key:MERCHANT_ADMIN_CREATE_COUPON_TEMPLATE_KEY
     * Val:
     * - 验证优惠券信息基本参数是否必填 —— 执行器 {@link CouponTemplateCreateParamNotNullChainFilter}
     * - 验证优惠券信息基本参数是否按照格式传递 —— 执行器 {@link CouponTemplateCreateParamBaseVerifyChainFilter}
     * - 验证优惠券信息基本参数是否正确,比如商品数据是否存在等 —— 执行器 {@link CouponTemplateCreateParamVerifyChainFilter}
     * - ......
     */
    private final Map<String, List<AbstractChainHandler>> abstractChainHandlerContainer = new HashMap<>();/**
     * 责任链组件执行
     *
     * @param mark         责任链组件标识
     * @param requestParam 请求参数
     */
    public void handler(String mark, T requestParam) {
        // 根据 mark 标识从责任链容器中获取一组责任链实现 Bean 集合
        List<AbstractChainHandler> abstractChainHandlers = abstractChainHandlerContainer.get(mark);
        if (CollectionUtils.isEmpty(abstractChainHandlers)) {
            throw new RuntimeException(String.format("[%s] Chain of Responsibility ID is undefined.", mark));
        }
        abstractChainHandlers.forEach(each -> each.handler(requestParam));
    }@Override
    public void run(String... args) throws Exception {
        // 从 Spring IOC 容器中获取指定接口 Spring Bean 集合
        Map<String, AbstractChainHandler> chainFilterMap = applicationContext.getBeansOfType(AbstractChainHandler.class);
        chainFilterMap.forEach((beanName, bean) -> {
            // 判断 Mark 是否已经存在抽象责任链容器中,如果已经存在直接向集合新增;如果不存在,创建 Mark 和对应的集合
            List<AbstractChainHandler> abstractChainHandlers = abstractChainHandlerContainer.getOrDefault(bean.mark(), new ArrayList<>());
            abstractChainHandlers.add(bean);
            abstractChainHandlerContainer.put(bean.mark(), abstractChainHandlers);
        });
        abstractChainHandlerContainer.forEach((mark, unsortedChainHandlers) -> {
            // 对每个 Mark 对应的责任链实现类集合进行排序,优先级小的在前
            unsortedChainHandlers.sort(Comparator.comparing(Ordered::getOrder));
        });
    }@Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

3.3使用方式

@Service
@RequiredArgsConstructor
public class ServiceImpl extends ServiceImpl<Mapper, DO> implements Service {
​
    private final ChainContext ChainContext;
  
    @Override
    public void createCouponTemplate(ReqDTO requestParam) {
        // 通过责任链验证请求参数是否正确
       ChainContext.handler(ChainBizMarkEnum.XXXXX.name(), requestParam);
        // xxxxxx
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2277680.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

练习:MySQL单表查询与多表查询

一.单表查询 创建worke数据库&#xff0c;在数据库底下创建worker表 mysql> create database worke; Query OK, 1 row affected (0.00 sec)mysql> show databases; -------------------- | Database | -------------------- | information_schema | | mysql …

HarmonyOS NEXT应用开发边学边玩系列:从零实现一影视APP (四、最近上映电影滚动展示及加载更多的实现)

在HarmonyOS NEXT开发环境中&#xff0c;可以使用多种组件和库来构建丰富且交互友好的应用。本文将展示如何使用HarmonyOS NEXT框架和nutpi/axios库&#xff0c;从零开始实现一个简单的影视APP的首页&#xff0c;主要关注最近上映电影的滚动展示及加载更多功能的实现。 开源项目…

卷积神经05-GAN对抗神经网络

卷积神经05-GAN对抗神经网络 使用Python3.9CUDA11.8Pytorch实现一个CNN优化版的对抗神经网络 简单的GAN图片生成 CNN优化后的图片生成 优化模型代码对比 0-核心逻辑脉络 1&#xff09;Anacanda使用CUDAPytorch2&#xff09;使用本地MNIST进行手写图片训练3&#xff09;…

客户案例:某家居制造企业跨境电商,解决业务端(亚马逊平台)、易仓ERP与财务端(金蝶ERP)系统间的业务财务数据对账互通

一、系统定义 1、系统定位&#xff1a; 数据中台系统是一种战略选择和组织形式&#xff0c;通过有型的产品支撑和实施方法论&#xff0c;解决企业面临的数据孤岛、数据维护混乱、数据价值利用低的问题&#xff0c;依据企业特有的业务和架构&#xff0c;构建一套从数据汇聚、开…

服务器一次性部署One API + ChatGPT-Next-Web

服务器一次性部署One API ChatGPT-Next-Web One API ChatGPT-Next-Web 介绍One APIChatGPT-Next-Web docker-compose 部署One API ChatGPT-Next-WebOpen API docker-compose 配置ChatGPT-Next-Web docker-compose 配置docker-compose 启动容器 后续配置 同步发布在个人笔记服…

辅助云运维

为客户提供运维支持&#xff0c;保障业务连续性。 文章目录 一、服务范围二、服务内容三、服务流程四、 服务交付件五、责任分工六、 完成标志 一、服务范围 覆盖范围 云产品使用咨询、问题处理、配置指导等&#xff1b; 云产品相关操作的技术指导&#xff1b; 云相关资源日常…

[Qt]常用控件介绍-多元素控件-QListWidget、QTableWidget、QQTreeWidget

目录 1.多元素控件介绍 2.ListWidget控件 属性 核心方法 核心信号 细节 Demo&#xff1a;编辑日程 3.TableWidget控件 核心方法 QTableWidgetItem核心信号 QTableWidgetItem核心方法 细节 Demo&#xff1a;编辑学生信息 4.TreeWidget控件 核心方法 核心信号…

Windows部署NVM并下载多版本Node.js的方法(含删除原有Node的方法)

本文介绍在Windows电脑中&#xff0c;下载、部署NVM&#xff08;node.js version management&#xff09;环境&#xff0c;并基于其安装不同版本的Node.js的方法。 在之前的文章Windows系统下载、部署Node.js与npm环境的方法&#xff08;https://blog.csdn.net/zhebushibiaoshi…

基于STM32设计的粮食仓库(粮仓)环境监测系统

一、前言 1.1 项目开发背景 随着现代农业的发展和粮食储存规模的扩大&#xff0c;粮仓环境的智能化监控需求日益增长。传统的粮仓管理方式通常依赖人工检测和定期巡查&#xff0c;效率低下且容易出现疏漏&#xff0c;无法及时发现潜在问题&#xff0c;可能导致粮食受潮、霉变…

【Linux】--- 进程的等待与替换

进程的等待与替换 一、进程等待1、进程等待的必要性2、获取子进程status3、进程等待的方法&#xff08;1&#xff09;wait&#xff08;&#xff09;函数&#xff08;2&#xff09;waitpid函数 4、多进程创建以及等待的代码模型5、非阻塞接口 轮询 二、进程替换1、替换原理2、替…

Vue2+OpenLayers添加/删除点、点击事件功能实现(提供Gitee源码)

目录 一、案例截图 二、安装OpenLayers库 三、安装Element-UI 四、代码实现 4.1、添加一个点 4.2、删除所有点 4.3、根据经纬度删除点 4.4、给点添加点击事件 4.5、完整代码 五、Gitee源码 一、案例截图 可以新增/删除标记点&#xff0c;点击标记点可以获取到当前标…

HTML中如何保留字符串的空白符和换行符号的效果

有个字符串 储值门店{{thing3.DATA}}\n储值卡号{{character_string1.DATA}}\n储值金额{{amount4.DATA}}\n当前余额{{amount5.DATA}}\n储值时间{{time2.DATA}} &#xff0c; HTML中想要保留 \n的换行效果的有下面3种方法&#xff1a; 1、style 中 设置 white-space: pre-lin…

GB44495-2024 汽车整车信息安全技术要求 - V2X部分前置要求

背景 GB 44495-2024《汽车整车信息安全技术要求》中关于V2X&#xff08;车与外界通信&#xff09;的部分&#xff0c;主要关注于通信安全要求&#xff0c;旨在确保车辆在与外部设备进行数据交互时的信息安全。其测试大致可分为消息层&#xff08;数据无异常&#xff09;、应用…

[PAT 甲级] 1179 Chemical Equation (DFS)

​ 题目翻译&#xff08;GPT&#xff09;&#xff1a; 1179 化学方程式 化学方程式是一种用符号和公式表示化学反应的方法&#xff0c;其中反应物在方程式的左侧&#xff0c;生成物在右侧。例如&#xff1a; CH₄ 2O₂ -> CO₂ 2H₂O 表示反应物为甲烷和氧气&#xff…

android分区和root

线刷包内容&#xff1a; 线刷包是一个完整的android镜像&#xff0c;不但包括android、linux和用户数据&#xff0c;还包括recovery等。当然此图中没有recovery,但是我们可以自己刷入一个。 主要分区 system.img 系统分区&#xff0c;包括linux下主要的二进制程序。 boot.img…

每日一题(五):n个正整数排列,求组合后最大数

目录 一、题目 二、题目分析 &#xff08;一&#xff09;明确需求 背景知识&#xff1a;字符串的比较与连接 1.字符串的比较 2.字符串的连接 (二)分析思路 三、将思路转换为程序 四、总结 一、题目 给定n个正整数a1,a2,……,an对这n个数进行排列&#xff0c;求组合后可以得到…

【STM32-学习笔记-3-】TIM定时器

文章目录 TIM定时器Ⅰ、TIM定时器函数Ⅱ、TIM_TimeBaseInitTypeDef结构体参数①、TIM_ClockDivision②、TIM_CounterMode③、TIM_Period④、TIM_Prescaler⑤、TIM_RepetitionCounter Ⅱ、定时器配置Ⅲ、定时器外部中断NVIC配置 TIM定时器 Ⅰ、TIM定时器函数 // 将定时器寄存器…

【Rust自学】12.2. 读取文件

12.2.0. 写在正文之前 第12章要做一个实例的项目——一个命令行程序。这个程序是一个grep(Global Regular Expression Print)&#xff0c;是一个全局正则搜索和输出的工具。它的功能是在指定的文件中搜索出指定的文字。 这个项目分为这么几步&#xff1a; 接收命令行参数读…

新垂直电商的社交传播策略与AI智能名片2+1链动模式S2B2C商城小程序的应用探索

摘要&#xff1a;随着互联网技术的不断进步和电商行业的快速发展&#xff0c;传统电商模式已难以满足消费者日益增长的个性化和多元化需求。新垂直电商在此背景下应运而生&#xff0c;通过精准定位、用户细分以及深度社交传播策略&#xff0c;实现了用户群体的快速裂变与高效营…

【ORACLE战报】2025.1月OCP | MySQL考试

2025.1月【最新考试成绩出炉】 OCP战报 MySQL 战报 部分学员成绩及证书