策略模式实现红包分配算法

桃李春风一杯酒,江湖夜雨十年灯。

1 前言

在前文中已经分享了模板和策略模式的实践SpringBoot-策略和模板模式的思考与实践,在本文中将结合红包算法的场景再次进行实践,主要还是分享红包计算的思考逻辑和心得。在前文中已经介绍了订单拆分的算法,红包的算法和订单的算法有相似的地方。

2 业务分析

对于红包,大家能想到的一定是抢红包的场景,因为这个是一个并发场景且是领取红包的场景,考察的知识点比较多,但是这里介绍的红包业务是需要全面覆盖的,需要从发红包开始,至于红包的领取,会在后续的文章来分享。红包的类型可以分为个人红包和群红包(群红包可以分为平分模式和拼手气模式),在本文中将着重介绍拼手气红包的分配算法。

对于平分模式的红包比较简单,采用算术评分是即可,在 java 中会出现除不尽的情况即尾差的问题,则需要使用减法来处理最后一个数据。

对于拼手气模式的红包,相对来说比较复杂一点,既要保证红包分配的均匀性,也要考虑到红包之间的差异,还有一个红包最小金额的问题。假设需要发 n 个红包,在计算第 i 个红包的随机金额时,随机数的范围最小值即红包的最小金额,最大金额的设置要保证至少有 (n - i) 个红包最小金额。即便是如此,也不能保证一次循环就可以得到所有的红包金额,所以还需要设置本次要分的最大金额要小于未分配金额的 m 倍,这样才可以保证一次循环分配所有的红包金额。

css 复制代码
# 假设需要分配 n 个红包红包分配总金额为 m ,红包分配的最小金额为 0.1 ,则每次分配的最小金额为 0.01
第i次要分配的红包金额随机数取数范围为
amt = [0.01,(m -p - 0.01*(n-i)) * 0.66]
p 为第 i 次已经分配的红包总金额
如果本次分配最大金额为剩余待分配金额的 k 倍,则系数为 k/(k +1 ), 0.66 即表示2倍,倍数越大,红包的极值差越大,否则就越小

3 红包算法

红包平分模式的算法比较简单,需要按照比例来计算每个红包的金额,在 java 编程中但凡涉及到除法,都会存在除不尽的情况,所以最后一个一定要使用减法,才能保证子单和主单的金额一致性

3.1 红包平分算法

红包平均算法就是使用算术平均方法,在 java 中对于四则运算中的除法需要考虑结果的保留位数,否则遇到除不尽的情况会报 Invalid rounding mode 的错误。最后一个红包需要使用减法来计算,否则单个红包的累计之和红包总金额不一致。在操作计算时,可以使用 hutools 中的 Numutils 工具类进行计算,可以很方便的实现计算。

3.2 拼手气算法

红包拼手气的算法如下图所示,核心的逻辑还是计算每个红包的具体金额,保证每个红包的差异性,也要保证红包间的均衡性。这里使用的是 N 倍余额算法。在计算过程中可以使用 Numutils 工具类实现便捷计算。

7 总结

在本文中,主要介绍了发红包的类型和红包算法的实现,在后续文章中将使用策略模式来实现红包的发放和领取,通过红包的业务增强了对订单金额计算深刻的认知,也拓展巩固了作者的业务理解,同时也对设计模式有了新的感悟和心得。项目 github 地址 springboot-auth

相关推荐
乐迪信息28 分钟前
防爆AI摄像机实时监测船舶异常姿态
大数据·人工智能·算法·安全·目标跟踪
Lovefoolself40 分钟前
Electron框架使用vue开发跨平台桌面工具应用-后台日志发送到前台和执行导入ZIP
后端
styshoo1 小时前
[NVSentinel] syslog-health-monitor模块分析
后端
Zane19941 小时前
自定义异常该继承 Exception 还是 RuntimeException,就看这一个问题
java·后端
风曳丷1 小时前
10|攻击如何跨越 Context、阶段与时间
后端
tyung1 小时前
znet 数据编解码:字节流怎么变成消息
后端·网络协议·go
爱喝可乐的中登1 小时前
SpringBoot 云边协同|智慧地铁 ISCS 改造实战第 10 篇:全网权限与数据隔离重构|线路‑车站‑专业三级 RBAC、边缘数据权限下沉
java·spring boot·重构
码视野1 小时前
基于 Spring Boot + Vue3 的【高校化学实验室安全准入考试与危化品配伍排查系统】设计与实现(含PRD/三端高保真源码/大屏)
前端·人工智能·spring boot·后端·安全·vue3
CarIise1 小时前
C语言结构体与链表
数据结构·算法
LXMXHJ1 小时前
springboot项目测试
java·spring boot·后端·测试