优惠券平台(一):基于责任链模式创建优惠券模板

前景概要

系统的主要实现是优惠券的相关业务,所以对于用户管理的实现我们简单用拦截器在触发接口前创建一个单一用户。

// 用户属于非核心功能,这里先通过模拟的形式代替。后续如果需要后管展示,会重构该代码
UserInfoDTO userInfoDTO = new UserInfoDTO("1810518709471555585", 
"pdd45305558318", 
1810714735922956666L);
UserContext.setUser(userInfoDTO);

优惠券模板创建业务

优惠券分为平台券和店铺券,平台券由平台运营人员创建和管理员审批,关系隶属于平台,用户使用后成本一般来说由平台和商家共同承担;而店铺券由商家在商家后台直接创建,无需审核,成本由店家独自承担。

设定优惠券的领取规则,消耗规则:

// 领取规则
JSONObject receiveRule = new JSONObject();
receiveRule.put("limitPerPerson", 1); // 每人限领
receiveRule.put("usageInstructions", "xxx"); // 使用说明
// 消耗规则
JSONObject consumeRule = new JSONObject();
consumeRule.put("termsOfUse", new BigDecimal("10")); // 使用条件 满 x 元可用
consumeRule.put("maximumDiscountAmount", new BigDecimal("3")); // 最大优惠金额
consumeRule.put("explanationOfUnmetC 3onditions", "xxx"); // 不满足使用条件说明
consumeRule.put("validityPeriod", 48); // 自领取优惠券后有效时间,单位小时

责任链模式

现有代码的问题

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

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

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

什么是责任链模式

责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,它允许将请求沿着一个处理链传递,直到链中的某个对象处理它。

核心部分代码:

@Component
public final class MerchantAdminChainContext<T> implements ApplicationContextAware, CommandLineRunner {private final Map<String, List<MerchantAdminAbstractChainHandler>> abstractChainHandlerContainer = new HashMap<>();
​/*** 责任链组件执行** @param mark         责任链组件标识* @param requestParam 请求参数*/public void handler(String mark, T requestParam) {// 根据 mark 标识从责任链容器中获取一组责任链实现 Bean 集合List<MerchantAdminAbstractChainHandler> 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));}
​@Overridepublic void run(String... args) throws Exception {// 从 Spring IOC 容器中获取指定接口 Spring Bean 集合Map<String, MerchantAdminAbstractChainHandler> chainFilterMap = applicationContext.getBeansOfType(MerchantAdminAbstractChainHandler.class);chainFilterMap.forEach((beanName, bean) -> {// 判断 Mark 是否已经存在抽象责任链容器中,如果已经存在直接向集合新增;如果不存在,创建 Mark 和对应的集合List<MerchantAdminAbstractChainHandler> 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));});}
​@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;}
}

逻辑流程图

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

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

相关文章

VsCode创建VUE项目

1. 首先安装Node.js和npm 通过网盘分享的文件&#xff1a;vsCode和Node&#xff08;本人电脑Win11安装&#xff09; 链接: https://pan.baidu.com/s/151gBWTFZh9qIDS9XWMJVUA 提取码: 1234 它们是运行和构建Vue.js应用程序所必需的。 1.1 Node安装&#xff0c;点击下一步即可 …

大模型产品Deepseek(五)、本地安装部署(Docker方式)

DeepSeek 本地部署指南 DeepSeek是一款高效的智能搜索与推荐引擎,除了通过云端API提供服务外,它还支持本地部署,让开发者可以完全控制数据和计算资源。通过本地部署,您可以将DeepSeek集成到内部系统中,在私有环境下运行模型,减少对外部API的依赖,同时提升数据隐私性与响…

JVM 中的四类引用:强、软、弱、虚

导言 在 Java 开发中&#xff0c;垃圾收集&#xff08;GC&#xff09;机制通过自动管理内存提升了开发效率。但你是否知道 JVM 通过四种引用类型&#xff08;强、软、弱、虚&#xff09;精细控制对象生命周期&#xff1f; 强引用&#xff08;Strong Reference&#xff09; 特…

数据结构--八大排序算法

1. 直接插入排序 当插入第 i(i>1) 个元素时&#xff0c;前面的 array[0],array[1],…,array[i-1] 已经排好序&#xff0c;此用 array[i] 的排序码与 array[i-1],array[i-2],… 的排序码顺序进行比较&#xff0c;找到插入位置即将 array[i] 插入&#xff0c;原来位置上的元素…

【C/C++算法】从浅到深学习---双指针算法(图文兼备 + 源码详解)

绪论&#xff1a;冲击蓝桥杯一起加油&#xff01;&#xff01; 每日激励&#xff1a;“不设限和自我肯定的心态&#xff1a;I can do all things。 — Stephen Curry” 绪论​&#xff1a; 本章是新开篇章也是算法的第一篇章----双指针算法&#xff0c;双指针算法是算法中非常…

Python内置函数map(), list(), len(), iter(), hex(), hash()的详细解析,包括功能、语法、示例及注意事项

1. map(function, iterable, ...) 功能&#xff1a;对可迭代对象中的每个元素应用指定函数&#xff0c;返回一个迭代器。 参数&#xff1a; function&#xff1a;要执行的函数&#xff08;可以是lambda表达式&#xff09;。 iterable&#xff1a;一个或多个可迭代对象&#x…

Win本地安装Ollama+本地运行大模型+Cherrystudio使用

0. 前言 本文主要介绍 win 本地安装 Ollama &#xff0c;本地部署 Ollama 的 deepseek-r1:7b 大模型&#xff0c;使用具有界面画操作的工具 Cherrystudio进行操作。文章内容仅供参考。 1. Ollama简介 ‌ ‌Ollama 是一个开源的框架&#xff0c;旨在本地运行大型语言模型…

用户点击商品埋点的实现方案

在高并发、可扩展性和高可用性的前提下&#xff0c;实现用户点击商品的埋点&#xff0c;方案应包括 数据采集、数据传输、数据存储和数据分析 四个主要环节。下面是一个完整的埋点实现方案&#xff1a; 1. 方案架构 整体流程&#xff1a; 前端埋点&#xff1a;用户点击商品时…

【C++】AVLTree(AVL树)简单模拟

文章目录 1.AVL树的结点2.AVL树的插入3.AVL树的旋转3.1 新节点插入较高左子树的左侧---左左&#xff1a;右单旋3.2 新节点插入较高右子树的右侧---右右&#xff1a;左单旋3.3 新节点插入较高左子树的右侧---左右&#xff1a;先左单旋再右单旋3.4 新节点插入较高右子树的左侧---…

零基础Vue入门6——Vue router

本节重点&#xff1a; 路由定义路由跳转 前面几节学习的都是单页面的功能&#xff08;都在专栏里面https://blog.csdn.net/zhanggongzichu/category_12883540.html&#xff09;&#xff0c;涉及到项目研发都是有很多页面的&#xff0c;这里就需要用到路由&#xff08;vue route…

【数据结构】(6) LinkedList 链表

一、什么是链表 1、链表与顺序表对比 不同点LinkedListArrayList物理存储上不连续连续随机访问效率O(N)O(1&#xff09;插入、删除效率O(1)O(N) 3、链表的分类 链表根据结构分类&#xff0c;可分为单向/双向、无头结点/有头节点、非循环/循环链表&#xff0c;这三组每组各取…

使用Pygame制作“俄罗斯方块”游戏

1. 前言 俄罗斯方块&#xff08;Tetris&#xff09; 是一款由方块下落、行消除等核心规则构成的经典益智游戏&#xff1a; 每次从屏幕顶部出现一个随机的方块&#xff08;由若干小方格组成&#xff09;&#xff0c;玩家可以左右移动或旋转该方块&#xff0c;让它合适地堆叠在…

(苍穹外卖)项目结构

苍穹外卖项目结构 后端工程基于 maven 进行项目构建&#xff0c;并且进行分模块开发。 1). 用 IDEA 打开初始工程&#xff0c;了解项目的整体结构&#xff1a; 对工程的每个模块作用说明&#xff1a; 序号名称说明1sky-take-outmaven父工程&#xff0c;统一管理依赖版本&…

【漫画机器学习】082.岭回归(或脊回归)中的α值(alpha in ridge regression)

岭回归&#xff08;Ridge Regression&#xff09;中的 α 值 岭回归&#xff08;Ridge Regression&#xff09;是一种 带有 L2​ 正则化 的线性回归方法&#xff0c;用于处理多重共线性&#xff08;Multicollinearity&#xff09;问题&#xff0c;提高模型的泛化能力。其中&am…

websocket自动重连封装

websocket自动重连封装 前端代码封装 import { ref, onUnmounted } from vue;interface WebSocketOptions {url: string;protocols?: string | string[];reconnectTimeout?: number; }class WebSocketService {private ws: WebSocket | null null;private callbacks: { [k…

【华为OD-E卷 - 115 数组组成的最小数字 100分(python、java、c++、js、c)】

【华为OD-E卷 - 数组组成的最小数字 100分&#xff08;python、java、c、js、c&#xff09;】 题目 给定一个整型数组&#xff0c;请从该数组中选择3个元素组成最小数字并输出 &#xff08;如果数组长度小于3&#xff0c;则选择数组中所有元素来组成最小数字&#xff09; 输…

在Vue3 + Vite 项目中使用 Tailwind CSS 4.0

文章目录 首先是我的package.json根据官网步骤VS Code安装插件验证是否引入成功参考资料 首先是我的package.json {"name": "aplumweb","private": true,"version": "0.0.0","type": "module","s…

AURIX TC275学习笔记4 官方GTM例程 GTM_TOM_PWM_1

文章目录 概述其他例程 代码分析IfxGtm_enable()IfxGtm_Cmu_enableClocks&#xff08;&#xff09;IfxGtm_Tom_Pwm_initConfig&#xff08;&#xff09;IfxGtm_Tom_Pwm_init&#xff08;&#xff09;IfxGtm_Tom_Pwm_start&#xff08;&#xff09;fadeLED() 概述 目的&#xf…

ASP.NET Core中间件的概念及基本使用

什么是中间件 中间件是ASP.NET Core的核心组件&#xff0c;MVC框架、响应缓存、身份验证、CORS、Swagger等都是内置中间件。 广义上来讲&#xff1a;Tomcat、WebLogic、Redis、IIS&#xff1b;狭义上来讲&#xff0c;ASP.NET Core中的中间件指ASP.NET Core中的一个组件。中间件…

app专项测试(网络测试流程)

一、网络测试的一般流程 step1&#xff1a;首先要考虑网络正常的情况 ① 各个模块的功能正常可用 ② 页面元素/数据显示正常 step2&#xff1a;其次要考虑无网络的情况 ① APP各个功能在无网络情况下是否可用 ② APP各个页面之间切换是否正常 ③ 发送网络请求时是…