基于模板设计模式开发优惠券推送功能以及对过期优惠卷进行定时清理

1.模板设计模式:

模板设计模式是一种常见的设计模式,主要作用是对 具体操作的 共有代码块进行提取,提升代码复用性。

那么说道代码复用性,首先想到的是抽象类而不是接口。

因为抽象类的本质就是为了代码复用,抽象类既可以包含抽象方法也可以包含具体方法。

在模板设计模式中,我们将 需要将原本共有的具体操作抽离并封装在抽象类的具体方法中。让抽象类的具体操作来实现需要被复用的逻辑。而其余的抽象方法是不同业务的 个性,各个业务可以按照自己的方式进行重写。这部分特性在模板设计模式中是为具体方法服务的。

2.开发优惠券推送功能

优惠券推送功能是根据excel导出方式来进行的。目前我们有一张优惠券,画像平台根据用户特性选取出符合这张优惠券的用户,从而导出一个excel表格,表格中装入的是符合发券特征的用户。我们的优惠券推送功能就是根据读取excel表格中的用户信息,将这张优惠券统一推送给目标用户。

对于优惠券发放,我们考虑到了定时发放和立即发放两种情况。由于定时发放使用传统的定时任务需要建立线程定时去扫描全表,造成数据库的较大开销,所以考虑使用RocketMQ来进行定时任务。

RocketMQ的延时消息任务,需要发送地址、消息以及发送时间三个参数。

public SendResult syncSendDelayTimeMills(String destination, Message<?> message, long delayTime) {return this.syncSend(destination, message, (long)this.producer.getSendMsgTimeout(), delayTime, DelayMode.DELAY_MILLISECONDS);
}

这是对应的rocketMQ的定时消息发送接口,需要destination,message,delayTime

2.1发送地址

对于不同的业务,建立不同的group,消费者会根据group从消息队列中接收自己想要的信息。

2.2消息

需要注意的是Message<?>是指上是Spring中的包import org.springframework.messaging.Message;

Message通过MessageBuilder进行构建,这部分内容就是消息实体。

2.3发送时间

delayTime就是指延迟发送的时间。

3.如何抽离出模板设计模式

由于我们的业务不仅有延时发送任务,还有立即发送任务,所以会为这两种任务设计消息发送类AbstractCommonSendProduceTemplate,很显然,这是共有的抽象类。

然后为不同的业务创建不同的实现类,继承AbstractCommonSendProduceTemplate。

3.1如何判断是立即发送还是延时发送?

我们只需要设计一个属性,根据属性的值来判断即可。这可以解决立即发送和延时发送的矛盾。在业务层无需再进行判断。

3.2具体如何完整实现模板设计模式?

在上面我们讲解了类的抽离,我们现在需要找立即发送与延时发送的区别,抽离出共性与特性。

共性很显然就是都需要使用rocketMQ进行消息发送。

1.特性:对于立即发送而言,需要的api不是syncSendDelayTimeMills而是syncSend,

public SendResult syncSend(String destination, Message<?> message, long timeout) {return this.syncSend(destination, message, timeout, 0);
}

timeout是超时时间。这是第一个特性。

2.处理的业务模块不同,在项目中,推送优惠券模块的推送功能可以是定时推送也可以是立即推送,包含这两种方式。

而对于优惠券创建模块的定时销毁过期优惠券功能目前只需要定时任务方式。

所以对于不同的业务,我们需要抽离出不同的事件,因为不同的业务需要的参数不同,这里我们的项目定义了两个事件类:CouponTaskExecuteEvent、CouponTemplateDelayEvent

基于上述的共性与特性,具体如何实现?

从顶层考虑,我们的目的是实现发送消息代码的复用,所以我们抽离代码的时候一般而言是先抽取主要逻辑,对应抽象类中的具体方法。

当具体方法因不同业务模块需要不同参数的时候我们再使用抽象方法对”个性“进行实现即可。也就是上述内容所说的抽象方法为具体方法服务的思想。

因为定时和立即发送api不同,所以我们需要一个dto类来传递一个属性来验证是定时发送还是立即发送。

所以现在我们需要创建一个共有的DTO类来辅助具体任务的开发。DTO应该包含多个业务的主要内容,所以对于这种模板设计模式而言,尽量使业务功能相近,不然在DTO设计时不好设计。

public class BaseSendExtendDTO {/*** 事件名称*/private String eventName;/*** 主题*/private String topic;/*** 标签*/private String tag;/*** 业务标识*/private String keys;/*** 发送消息超时时间*/private Long sentTimeout;/*** 具体延迟时间*/private Long delayTime;
}

事件名称用于分辨不同功能,主题用于不同消息类型的监听,如果是立即发送,则delayTime为null,用于判断信息类型。

需要注意的是,该DTO类只是用于辅助消息发送,和真正的业务无关。比如说用于判别目前的任务是那个业务模块,执行业务模块中的哪个任务,任务的信息发送是什么模式等等。

比如在:

public SendResult syncSendDelayTimeMills(String destination, Message<?> message, long delayTime) {

return this.syncSend(

destination, message,

(long)this.producer.getSendMsgTimeout(),

delayTime, DelayMode.DELAY_MILLISECONDS);

}

这个 发送api中,DTO类只控制destination与delayTime,而message是由事件决定的。

4.总结

通过上述DTO可以使得不同功能模块找到自己的实现方式(比如立即发送和延时发送就是通过判别DTO中delayTime是否为null,再比如通过Topic使得不同消费者只监听自己的内容)。

通过两个事件类对两个功能模块所需属性做了区分,实质上最终传递的内容就是对应的事件。

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

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

相关文章

对象的finalization机制Test1

Java语言提供了对象终止(finalization)机制来允许开发人员自定义对象被销毁之前的处理逻辑。当垃圾回收器发现没有引用指向一个对象时&#xff0c;通常接下来要做的就是垃圾回收&#xff0c;即清除该对象&#xff0c;而finalization机制使得在清除此对象之前&#xff0c;总会先…

RJ45 连接器(水晶头)的引脚定义

RJ45连接器核心定义 【】物理结构 8个金属触点&#xff08;Pin 1至Pin 8&#xff09;的透明塑料插头&#xff0c;带塑料卡榫。 引脚编号规则 卡榫朝下&#xff0c;金属触点面向自己时&#xff1a; 最左侧为 Pin 1 最右侧为 Pin 8 顺序&#xff1a;Pin 1 → Pin 2 → Pin 3 → P…

小架构step系列08:logback.xml的配置

1 概述 logback.xml配置文件的详细配置&#xff0c;很多地方都说得比较细&#xff0c;本文主要从几个重点来看一下原理&#xff0c;了解原理能够帮助确定哪些应该配置&#xff0c;以及如何配置。 logback.xml是为打印日志服务的&#xff0c;打印的内容一般打印到控制台(Conso…

STM32中SPI协议详解

前言 在嵌入式系统中&#xff0c;设备间的数据传输协议多种多样&#xff0c;SPI&#xff08;Serial Peripheral Interface&#xff0c;串行外设接口&#xff09;凭借其高速、全双工、易用性等特点&#xff0c;成为连接STM32与高速外设&#xff08;如OLED屏、Flash芯片、AD转换器…

TypeScript 接口全解析:从基础到高级应用

TypeScript 接口全解析&#xff1a;从基础到高级应用在 TypeScript 中&#xff0c;接口是定义数据结构和行为规范的强大工具&#xff0c;它能够显著提升代码的可读性、可维护性和类型安全性。本文将全面讲解 TypeScript 接口的相关知识点&#xff0c;从基础语法到高级特性&…

主存(DRAM)是什么?

主存&#xff08;DRAM&#xff09;是什么&#xff1f; 主存&#xff08;DRAM&#xff09;详解 主存&#xff08;Main Memory&#xff09; 通常由 DRAM&#xff08;Dynamic Random Access Memory&#xff0c;动态随机存取存储器&#xff09; 构成&#xff0c;是计算机系统中用于…

Python 机器学习核心入门与实战进阶 Day 6 - 模型保存与加载(joblib / pickle)

✅ 今日目标 掌握如何将训练好的模型持久化保存到文件熟悉两种主流保存方式&#xff1a;joblib 和 pickle加载模型并应用于新数据预测实现完整的“训练 → 保存 → 加载 → 预测”流程为后续部署做准备&#xff08;如 Flask、FastAPI&#xff09;&#x1f9f0; 一、模型保存工具…

【SigNoz部署安装】Ubuntu环境部署SigNoz:Docker容器化监控的全流程指南

文章目录前言1.关于SigNoz2.本地部署SigNoz3.SigNoz简单使用4. 安装内网穿透5.配置SigNoz公网地址6. 配置固定公网地址前言 在分布式架构主导的现代运维体系中&#xff0c;系统性能监控正面临范式变革的关键转折。当微服务架构遭遇服务雪崩、无服务器架构出现冷启动延迟等复杂…

NV298NV312美光固态闪存NW639NW640

美光固态闪存技术全景解析&#xff1a;从NV298到NW640的深度探索近年来&#xff0c;美光科技凭借其在3D NAND闪存技术上的持续突破&#xff0c;推出了多款备受市场关注的固态硬盘产品。本文将从技术评测、产品对比、市场趋势、用户反馈及应用场景等多个维度&#xff0c;深入剖析…

2025.07.04【服务器】|使用万兆网卡提升服务器间互联速度,实现快速数据传输

文章目录1. **万兆网卡概述**2. **为什么选择万兆网卡**3. **万兆网卡配置与安装**3.1 **安装网卡**3.2 **安装驱动程序**3.3 **检查网卡状态**4. **配置网络接口**4.1 **Linux 系统配置**4.2 **Windows 系统配置**5. **优化性能**5.1 **使用多线程传输**5.2 **开启 TCP/UDP 窗…

光伏发电量精准估算,提升投资效益

在光伏产业规模化发展进程中&#xff0c;准确估算光伏发电量是提升项目投资效益的关键环节。科学的发电量预测不仅能为项目可行性研究提供依据&#xff0c;更能在电站全生命周期内优化运营策略&#xff0c;实现投资回报最大化。基于多维度数据整合与智能算法构建的精准预测体系…

Linux的互斥锁、Linux的POSIX信号量(二值、计数)、RTOS的二值信号量

锁和信号量最大的区别就是:锁严格要求 “谁占用谁释放”,而信号量允许 “一个任务 / 线程释放,另一个任务 / 线程获取”。 特性互斥锁(Mutex)POSIX 信号量(Semaphore)初始状态初始为 “锁定”(PTHREAD_MUTEX_INITIALIZER),需显式获取(pthread_mutex_lock)。初始值可…

基于Java+SpringBoot 协同过滤算法私人诊所管理系统

源码编号&#xff1a;S607源码名称&#xff1a;基于SpringBoot5的协同过滤算法的私人诊所管理系统用户类型&#xff1a;双角色&#xff0c;患者、医生、管理员数据库表数量&#xff1a;15 张表主要技术&#xff1a;Java、Vue、ElementUl 、SpringBoot、Maven运行环境&#xff1…

什么是DINO?

DINO 是一个由 Meta AI (当时的 Facebook AI) 在 2021 年提出的自监督学习框架&#xff0c;其全称是 “self-DIstillation with NO labels”&#xff0c;直译为“无标签的自我蒸馏”。这个名字精准地概括了它的核心思想。 DINO 的出现是一个里程碑&#xff0c;因为它首次有力地…

如何在 Android Framework层面控制高通(Qualcomm)芯片的 CPU 和 GPU。

如何在 Android Framework层面控制高通&#xff08;Qualcomm&#xff09;芯片的 CPU 和 GPU。 参考&#xff1a;https://blog.csdn.net/YoungHong1992/article/details/117047839?utm_source%20%20uc_fansmsg 作为一名 Framework 开发者&#xff0c;您拥有系统级的权限&#…

程序员在线接单

十年Java全栈工程师在线接单Java程序代做&#xff0c;兼职接单&#xff0c;系统代做&#xff0c;二次开发&#xff0c;网站开发部署&#xff0c;项目合作&#xff0c;商业项目承包 全栈开发&#xff0c;支持定制各种管理系统、小程序 商用或个人使用等项目都接 服务二: Java调试…

Python 异步爬虫(aiohttp)高效抓取新闻数据

一、异步爬虫的优势 在传统的同步爬虫中&#xff0c;爬虫在发送请求后会阻塞等待服务器响应&#xff0c;直到收到响应后才会继续执行后续操作。这种模式在面对大量请求时&#xff0c;会导致大量的时间浪费在等待响应上&#xff0c;爬取效率较低。而异步爬虫则等待可以在服务器…

Jenkins Pipeline(二)

1.Pipeline 变量 在 Jenkins 管道&#xff08;Pipeline&#xff09;中&#xff0c;变量是一种非常有用的功能&#xff0c;它们可以帮助你在构建过程中存储和传递数据。Jenkins 管道支持多种方式来定义和使用变量&#xff0c;包括环境变量、脚本变量以及全局变量。 1.2 脚本变…

springsecurity02

提前打开Redis1&#xff09;通过内置的用户名和密码登录spring-boot-starter-security.jar2&#xff09;使用自定义用户名和密码登录UserDetailService自定义类实现UserDetailService接口&#xff0c;重写loadUserByUsername方法class UserDetailServiceImpl implements UserDe…

Apache组件遭大规模攻击:Tomcat与Camel高危RCE漏洞引发数千次利用尝试

漏洞态势分析帕洛阿尔托网络公司Unit 42团队最新研究报告显示&#xff0c;针对Apache Tomcat和Apache Camel关键漏洞的网络攻击正在全球激增。2025年3月披露的这三个远程代码执行&#xff08;RCE, Remote Code Execution&#xff09;漏洞——CVE-2025-24813&#xff08;Tomcat&…