设计模式之模板方法实现抽奖功能

news2024/9/19 21:00:42

1.项目背景

接到一个需求,实现电商营销模块的圆盘抽奖功能。如果大家有关注市面上的抽奖,大致也是圆盘抽奖、九宫格抽奖,随机抽球等等。尤其是电商行业,会有各种各样的活动,因此也会出现各式各样的抽奖,那么如何更好写出抽奖模块的代码呢?基于博主涉及的业务需求,决定采用设计模式的模板方法

抽奖功能主要做几件事分别是:1.初始化奖品  2.抽奖  3.发放奖品 

那么这三件事,其实就放到模板方法的抽象类。
AbstractLotteryBaseTemplate 基础抽奖类

draw()是核心抽奖方法,里面分别调用了 executeDraw(),sendGift(),不管哪个实现类实现后,只需要调用draw()即可。具体大家可以往下看。最后会有具体调用。

/**
 * @description: 抽奖模板方法基础实现
 * @author: llk
 * @date: 2022/8/29
 */
public abstract class AbstractLotteryBaseTemplate {


    /**
     * @description: 执行抽奖
     * @author: llk
     * @date: 2022/8/29
     */
    abstract protected LotteryPrize executeDraw(Long lotteryId);

    /**
     * @description: 发放奖品
     * @author: llk
     * @date: 2022/8/29
     */
    abstract protected void sendGift(LotteryPrize lotteryPrize);

    /**
     * @description: 初始化奖品
     * @author: llk
     * @date: 2022/8/26
     */
    private void initLotteryPrize(Long lotteryId,List<LotteryPrize> lotteryPrizeList) {

        // todo

    }

    /**
     * @description: 开始抽奖
     * @author: llk
     * @date: 2022/8/26
     */
    public LotteryDrawResultServiceResp draw(Long lotteryId){

        //0.基础校验
        if(userId == null || userId == 0L){
            throw new ResultException("用户id不能为空");
        }
        if(lotteryId == null || lotteryId == 0L){
            throw new ResultException("抽奖ID不能为空");
        }
        Lottery lottery = lotteryDaoService.getById(lotteryId);
        if(lottery == null){
            throw new ResultException("不存在此抽奖活动");
        }

        //1.校验抽奖模块
        validLottery(lottery,lotteryPrizeList);

        //2.校验个人抽奖限制,如是否有权限,抽奖次数限制
        validPersonDraw(lotteryId, userId, lotteryUserCount);

        //3.初始化礼品概率队列
        initLotteryPrize(lotteryId,lotteryPrizeList);

        //4.抽奖
        LotteryPrize resultPrize = executeDraw(lotteryId);

        //5. 继续写一些核心业务,譬如抽奖次数减 1,抽奖结果入库等

        //6.发放奖品
        sendGift(lotteryPrize);

    }
}

大家可以看到 executeDraw(),sendGift()已经定义成了抽象方法,意味着这些核心关键的代码,有具体的抽奖实现类实现。因为不同的抽奖业务会有不同的规则限制和奖品发放。譬如:

圆盘抽奖:executeDraw里面的实现是用户必须下单了某商品才能抽奖。

                  sendGift里面发放的积分使我们电商系统的,直接调我们接口即可。

红包抽奖:executeDraw里面的实现是用户领了优惠券才能抽奖。

                  sendGift里面发京东卡,需要对接京东。

大家可以看到,不同的抽奖方式,两块的抽奖的内容不一样。但是初始化奖品等等,基础抽奖校验是一样的。

接下来给大家看下具体的具体后抽奖实现类。

TurntableLotteryTemplate 圆盘抽奖

/**
 * @description: 转盘抽奖
 * @author: llk
 * @date: 2022/8/29
 */
public class TurntableLotteryTemplate extends AbstractLotteryBaseTemplate{

     @Override
    protected LotteryPrize executeDraw(Long lotteryId) {

        // 校验用户必须下单了某商品才能抽奖
        return resultPrize;
    }

    @Override
    protected void sendGift(LotteryPrize lotteryPrize) {

        // 发放积分礼品
    }

​​​​​​​}
RedBagLotteryTemplate 红包抽奖
/**
 * @description: 转盘抽奖
 * @author: llk
 * @date: 2022/8/29
 */
public class TurntableLotteryTemplate extends AbstractLotteryBaseTemplate{

     @Override
    protected LotteryPrize executeDraw(Long lotteryId) {

        // 校验用户领了优惠券才能抽奖
        return resultPrize;
    }

    @Override
    protected void sendGift(LotteryPrize lotteryPrize) {

        // 发放京东卡,调京东第三方接口
    }

​​​​​​​}

最后的使用就是这样,各个抽奖方式的具体实现类直接调用draw()抽奖方法即可。


public LotteryDrawResultServiceResp draw(Long lotteryId) {

    Lottery lottery = daoService.getById(lotteryId);
    if(lottery == null){
        throw new ResultException("不存在此抽奖活动");
    }

    //具体哪个抽奖方式由开发自行去定义用哪个方式
    if(LotteryActivityTypeEnum.RED_BAG.getKey().equals(lottery.getActivityType())){
        return redBagLotteryTemplate.draw(lotteryId);
    }

    return turntableLotteryTemplate.draw(lotteryId);
}

最后,博主营销模块抽奖方式目前只有红包和圆盘,后续可能会有九宫抽奖,那么只需要实现AbstractLotteryBaseTemplate ,写自己的特殊的业务实现executeDraw(),sendGift()即可。这样就可以省略各种各样的校验等等,代码也易于维护。 

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

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

相关文章

【InnoDB 存储引擎】15.7.1 InnoDB Locking(锁实验,重要)

文章目录 1 关于 Record Lock 的实验1.1 实验 1&#xff1a;没有主键时的如何锁定1.2 实验 1&#xff08;续&#xff09;&#xff1a;带着问题继续实验1.3 实验 2&#xff1a;有主键时如何锁定 2 关于 Next-Key Lock 的实验2.1 实验 3&#xff1a;如何确定算法的锁定范围2.2 实…

HTML期末作业-精仿故宫模板(HTML+CSS+JavaScript)

期末作业完成&#xff01;我仿了故宫官网&#xff0c;老师给了90分。现在分享给大家&#xff01; 首页包含功能&#xff1a; 轮播图&#xff1a;在首页顶部设置一个可自动轮播的图片展示区域&#xff0c;展示多张宣传图片或产品图片&#xff0c;提升页面的视觉效果和吸引力。…

从0训练一个神经网络分类器

从0训练一个神经网络分类器 0. 关于数据&#xff1f; 训练一个图像分类器1. 使用torchvision可以非常容易地加载CIFAR10。2. 定义一个卷积神经网络3. 定义损失函数和优化器4. 训练网路5. 在测试集上测试网络6. 检测网络在整个测试集上的结果如何。7. 在识别哪一个类的时候好&am…

MySQL基操例题

Ⅰ创建数据库使用create语句&#xff1a; create database 数据库名&#xff1b; Ⅱ创建表同理&#xff1a; create table if not exists 表名 &#xff08; 字段名 数据类型 主键 约束&#xff0c; 字段名 数据类型 主键 约束&#xff09; 设置存储引擎和字符集&#xff1b; …

Text-Augmented Open Knowledge Graph Completion viaPre-Trained Language Models

摘要 开放知识图谱(KG)完成的任务是从已知的事实中得出新的发现。增加KG完成度的现有工作需要(1)事实三元组来扩大图推理空间,或(2)手动设计提示从预训练的语言模型(PLM)中提取知识,表现出有限的性能,需要专家付出昂贵的努力。为此,我们提出了TAGREAL,它自动生成高质量的…

【youcans动手学模型】SENet 模型及 PyTorch 实现

欢迎关注『youcans动手学模型』系列 本专栏内容和资源同步到 GitHub/youcans 【youcans动手学模型】SENet 模型 【经典模型】SENet 模型-Cifar10图像分类1. SENet 卷积神经网络模型1.1 模型简介1.2 论文介绍1.3 分析与讨论 2. 在 PyTorch 中定义 SENet 模型类2.1 定义 SE Block…

STL好难(5):stack的使用

目录 1.stack的介绍和使用&#xff1a; 2.stack的使用 3.有关stack的练习题&#xff1a; &#x1f349;最小栈 &#x1f349;栈的压入、弹出序列 4.stack的模拟实现&#xff1a; 1.stack的介绍和使用&#xff1a; 点击查看stack的文档介绍 1. stack是一种容器适配器&#…

(vue)element-ui表格中插入switch开关

(vue)element-ui表格中插入switch开关 效果&#xff1a; <el-table-column property"enabled" label"启用/禁用" width"150"><template slot-scope"scope"> <el-switchv-model"scope.row.enabled"active-co…

动态规划之746 使用最小花费爬楼梯(第3道)

题目&#xff1a; 给你一个整数数组 cost &#xff0c;其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用&#xff0c;即可选择向上爬一个或者两个台阶。 你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。 请你计算并返回达到楼梯顶部的最低花费…

差分学习笔记

1.前言 同步于 c n b l o g s cnblogs cnblogs 发布。 前置芝士&#xff1a; 基本树上操作&#xff0c;lca。&#xff08;用于树上差分。&#xff09; 如有错误&#xff0c;欢迎各位大佬指出。&#xff08;顺便复习一下远古算法。&#xff09; 2.什么是差分 我们先给定一…

AR增强现实技术解决企业远程协作需求

随着科技的不断发展&#xff0c;AR(增强现实)远程协同系统已经成为了一种新型的工作方式。这种系统利用AR技术将虚拟信息叠加到现实世界中&#xff0c;从而实现异地高效协作。 由广州华锐互动开发的AR远程协同系统&#xff0c;广泛应用于各个行业的远程协作场景中&#xff0c;…

44. 通配符匹配(从暴力递归到动态规划)

题目链接&#xff1a;力扣 所有的动态规划都可以使用暴力递归求解&#xff0c;如果推导dp方程比较困难&#xff0c;可以先使用暴力递归进行尝试&#xff0c;然后将从递归改为动态规划&#xff0c;这种方式在dp方程求解困难的情况下非常有效&#xff0c;而且从递归修改为动态规划…

计算机网络?

那么这样能通过审核吗&#xff1f;

二次元古代美女【InsCode Stable Diffusion美图活动一期】

二次元古代美女【InsCode Stable Diffusion美图活动一期】 一、前言二、初识 InsCode三、 试玩 Stable Diffusion 模型1.阅读Stable Diffusion 模型在线引导说明2.实际体验 Stable Diffusion 模型 四、模型相关版本和参数配置&#xff1a;五、图片生成提示词与反向提示词六、种…

游戏术语英语

王者荣耀英文术语大全&#xff01;玩这么久你都听懂了吗&#xff1f; 王者荣耀AP、AD、ADC、AOE等专业术语大全_乐游网 Operating System win2003, winXP, win7, win10 MacOS Game Platform 游戏平台 TGP&#xff08;Tencent Game Platform &#xff09; PC &#xff08;Per…

Linux上部署docker与docker-compose的步骤

Centos上部署docker与docker-compose的步骤 linux系统版本为Centos7.2 第一步-检查前置条件是否符合部署docker 64-bit 系统 kernel 3.10 使用uname -r 检查内核版本&#xff0c;返回的值大于3.10即可。 Centos 7.2的kernel是&#xff1a;3.10.0-327&#xff0c;刚好满足条件…

【算法与数据结构】225、LeetCode用队列实现栈

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;第一种解法是利用两个队列&#xff0c;一个用作输出队列&#xff0c;一个用作备份队列。主要难点在于p…

<Java导出Excel> 4.0 Java实现Excel动态模板字段增删改查

思路&#xff1a; 主要是同时操作两张表&#xff1a;一张存储数据的表&#xff0c;一张存储模板字段的表&#xff1b; 查询&#xff1a;只查询模板字段的表&#xff1b; 新增&#xff0c;修改&#xff0c;删除&#xff1a;需要同时操作两张表中的字段 如果两张表字段不一致&…

51单片机--点亮LED灯和流水灯

文章目录 前言LED模块的原理点亮一个LED灯LED灯的闪烁LED流水灯 前言 大家好&#xff0c;这里是诡异森林。我使用的是普中科技的A2的51开发板&#xff0c;适合新手入门。用到的应用是Keil5和Stc-isp&#xff0c;第一个软件主要用来写代码的&#xff0c;第二个是将代码程序输送…

RocketMQ5.0--部署与实例

RocketMQ5.0–部署与实例 一、Idea调试 1.相关配置文件 在E:\rocketmq创建conf、logs、store三个文件夹。从RocketMQ distribution部署目录中将broker.conf、logback_namesrv.xml、logback_broker.xml文件复制到conf目录。如下图所示。 其中logback_namesrv.xml、logback_b…