十分钟利用springboot写电商支持多种优惠券规则,使用策略模式替代大量的if-else

news2024/12/30 4:16:05

前言            

        在开发电商折扣模块的时候经常会碰到各种优惠规则,那么就会碰到很多条件判断,冗余各种if-else的代码使得维护困难,此时就可以用策略模式来解决,替代大量的冗余判断条件代码,精简代码结构。
        策略模式是一种行为模式,也是替代大量ifelse的利器。它所能帮你解决的是场景,一般是具有同类可替代的行为逻辑算法场景。比如;不同类型的交易方式(信用卡、支付宝、微信)、生成唯一ID策略(UUID、DB自增、DB+Redis、雪花算法、Leaf算法)等,都可以使用策略模式进行行为包装,供给外部使用。

1、定义优惠券折扣接口类

/**
 * @describe:优惠卷折扣计算接口
 * 1. 直减卷
 * 2. 满减卷
 * 3. 折扣卷
 * 4. N元购
 */
public interface ICouponDiscount<T> {
    /**
     *
     * @param couponInfo 券折扣信息;直减、满减、折扣、N元购
     * @param skuPrice 商品价格
     * @return 优惠后金额
     */
    BigDecimal discountAmount(T couponInfo, BigDecimal skuPrice);
}

2、实现折扣接口

  • 满减规则

/**
 * @describe:满减
 */
public class MJCouponDiscount implements ICouponDiscount<Map<String,String>> {
    /**
     * 满减计算
     *1. 判断满足x元后-n元,否则不减
     *2. 最低支付金额1元
     * @param couponInfo
     * @param skuPrice
     * @return
     */
    @Override
    public BigDecimal discountAmount(Map<String, String> couponInfo, BigDecimal skuPrice) {
        //满100
        String x = couponInfo.get("x");
        //减10
        String y = couponInfo.get("y");
        //小于商品金额条件,直接返回
        if(skuPrice.compareTo(new BigDecimal(x)) < 0){
            return skuPrice;
        }
        //减去优惠金额判断
        BigDecimal discountAmount = skuPrice.subtract(new BigDecimal(y));
        //满减后价格小于等于0,那么支付最低1元
        if(discountAmount.compareTo(BigDecimal.ZERO) < 1) return BigDecimal.ONE;
        return discountAmount;
    }
}
  • N元购规则

/**
 * @describe:N元购
 */
public class NYGCouponDiscount implements ICouponDiscount<Double> {
    /**
     * n元购购买
     * 1. 无论原价多少钱都固定金额购买
     */
    @Override
    public BigDecimal discountAmount(Double couponInfo, BigDecimal skuPrice) {
        return new BigDecimal(couponInfo);
    }
}
  • 折扣规则

/**
 * @describe:
 */
public class ZKCouponDiscount implements ICouponDiscount<Double> {
    /**
     * 折扣计算
     * 1. 使用商品价格乘以折扣比例,为最后支付金额
     * 2. 保留两位小数
     * 3. 最低支付金额1元
     */
    @Override
    public BigDecimal discountAmount(Double couponInfo, BigDecimal skuPrice) {
        //保留两位小数,并向上取整
        BigDecimal discountAmount = skuPrice.multiply(new BigDecimal(couponInfo)).setScale(2, BigDecimal.ROUND_HALF_UP);
        if(discountAmount.compareTo(BigDecimal.ZERO) < 1) return BigDecimal.ONE;
        return discountAmount;
    }
}
  • 直接减规则

/**
 * @describe:直减
 */
public class ZjCouponDiscount implements ICouponDiscount<Double> {
    /**
     * 直减计算
     * 1. 使用商品价格减去优惠价格
     * 2. 最低支付金额1元
     */
    @Override
    public BigDecimal discountAmount(Double couponInfo, BigDecimal skuPrice) {
        BigDecimal discountAmount = skuPrice.subtract(new BigDecimal(couponInfo));
        if(discountAmount.compareTo(BigDecimal.ZERO) < 1) return BigDecimal.ONE;
        return discountAmount;
    }
}

3、策略上下文

        定义策略的上下文,策略控制器,通过控制器调用不同的优惠策略

/**
 * @describe:策略控制器
 */
public class Context <T>{

    private ICouponDiscount<T> couponDiscount;

    public Context(ICouponDiscount<T> couponDiscount) {
        this.couponDiscount = couponDiscount;
    }
    public BigDecimal discountAmount(T couponInfo,BigDecimal skuPrice){
        return couponDiscount.discountAmount(couponInfo,skuPrice);
    }
}

4、编写测试类(调用方法)

        调用控制器,走不同的折扣规则

@Test
public void test(){
    // 直减;100-10,商品100元
    Context<Double> context = new Context<Double>(new ZJCouponDiscount());
    BigDecimal discountAmount = context.discountAmount(10D, new BigDecimal(100));
    logger.info("测试结果:直减优惠后金额 {}", discountAmount);
}

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

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

相关文章

建筑行业的重要工具—— 智慧工地管理平台(java源码)

系统定义&#xff1a; 智慧工地管理平台系统是一种集成了先进的信息技术、物联网技术、移动互联网技术等多种技术的工地管理系统。它能够对工地的整个生命周期进行全面的管理&#xff0c;包括工地的规划、设计、施工、监控、验收等各个环节。通过信息化手段&#xff0c;提高了工…

拯救者Legion Y9000K 2021H(82K6)原厂oem预装Win11系统镜像

lenovo联想拯救者Y9000K(82K6)原装出厂Windows11系统安装包下载&#xff0c;恢复出厂开箱状态 链接&#xff1a;https://pan.baidu.com/s/1DGWU7gctJerff6LJrgHD5w?pwdrbs5 提取码&#xff1a;rbs5 原装出厂系统自带所有驱动、出厂主题壁纸、系统属性联机支持标志、Office…

C++从入门到精通 第十四章(STL容器)【下】

写在前面&#xff1a; 本系列专栏主要介绍C的相关知识&#xff0c;思路以下面的参考链接教程为主&#xff0c;大部分笔记也出自该教程&#xff0c;笔者的原创部分主要在示例代码的注释部分。除了参考下面的链接教程以外&#xff0c;笔者还参考了其它的一些C教材&#xff08;比…

基础数据结构与相关C++ STL容器

文章目录 数组arrayvector 栈和队列dequestackqueue 堆heappriority_queue 链表listforward_list 树setmapmultisetmultimap 哈希表unordered_setunordered_mapunordered_multisetunordered_multimap 图 数组 array 不开口的连续线性空间&#xff0c;支持随机访问。 array是…

【C->Cpp】由C迈向Cpp(4)

目录 &#xff08;一&#xff09;内联函数 &#xff08;二&#xff09;关键字auto &#xff08;三&#xff09;范围for &#xff08;四&#xff09;nullptr 正文开始&#xff1a; &#xff08;一&#xff09;内联函数 宏定义&#xff1a; C的内联函数是在C语言宏的基础上提出…

怎样开发Apple Vision Pro应用?以应用开发者角度体验苹果的开发文档

▲ 搜索“大龙谈智能内容”关注公众号▲ 最近&#xff0c;苹果公司推出了革命性的产品Apple Vision Pro&#xff0c;全世界震惊。下边这个视频在社交网络上得到了大量转发&#xff1a; 在大家兴奋的围观之际&#xff0c;已经有人在规划能做些什么了。 有朋友问大龙有什么Vi…

妨碍做出正确决策的5种认知谬误

人类的大脑在极端情况下会呈现出不可理喻的一面&#xff0c;从而妨碍我们做出正确的决策。本文介绍了5种常见的认知谬误&#xff0c;识别并克服这些认知谬误&#xff0c;可以帮助我们更好的决策。原文: Want to Make Better Decisions? Avoid These 5 Cognitive Distortions 我…

Python中类创建和实例化过程

嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 一、 type() 1、创建类的两种方式 方式一 class MyClass(object):def func(self,name):print(name)myc MyClass()print(MyClass, type(MyClass)) print(myc, type(myc))我们创建了一个名为MyClass的类&#xff0c;并实例化…

书生·浦语大模型实战营-第四课笔记

期待已久的微调课 一、Finetune 增量预训练和指令跟随是两种微调模式&#xff0c;即两种微调策略。 1&#xff09;增量预训练 投喂新的领域知识即可&#xff0c;例如书籍、文章、代码 2&#xff09;指令跟随 采用高质量对话和问答数据进行训练 二、LoRA与QLoRA 两…

35、IO进程线程/多线程实现文件读写20240221

一、使用多线程完成两个文件的拷贝&#xff0c;第一个线程拷贝前一半&#xff0c;第二个线程拷贝后一半&#xff0c;主线程回收两个线程的资源。 代码&#xff1a; #include<myhead.h> typedef struct //类型重定义结构体 {const char *src;const char *dest;int start…

vue3总结

1 setup 概述 setup是Vue3中一个新的配置项个函数, 包含数据、方法等&#xff0c;是组合api的“舞台”。 特点如下&#xff1a; setup函数返回的对象中的内容&#xff0c;可直接在模板中使用。setup中访问this是undefined。setup函数会在beforeCreate之前调用&#xff0c;它…

人工智能深度学习

目录 人工智能 深度学习 机器学习 神经网络 机器学习的范围 模式识别 数据挖掘 统计学习 计算机视觉 语音识别 自然语言处理 机器学习的方法 回归算法 神经网络 SVM&#xff08;支持向量机&#xff09; 聚类算法 降维算法 推荐算法 其他 机器学习的分类 机器…

Spring Cloud Gateway 中文文档

Spring Cloud Gateway 中文文档 官方文档 该项目提供了一个建立在Spring Ecosystem之上的API网关&#xff0c;包括&#xff1a;Spring 5&#xff0c;Spring Boot 2和Project Reactor。 Spring Cloud Gateway旨在提供一种简单而有效的方式来对API进行路由&#xff0c;并为他们提…

奇异递归模板模式应用5-静态多态

动态多态&#xff1a;C动态多态是利用虚函数特性实现的&#xff0c;即基类指针(引用&#xff09;指向派生类指针(引用)。由于虚函数的实现是在运行期进行的&#xff0c;因而会产生运行期开销&#xff08;虚表指针偏移&#xff0c;与分支预测器和CPU指令流水线相关&#xff09;。…

window10中安装Docker Desktop(2024最新)

1、安装概述? 博客创造时间:2024年2月20日。 Docker在Linux中的安装相对较简单,但是在window中的安装总是会出现很多的问题。 新版本Docker Desktop安装的前提条件: 1、现在Docker Desktop默认使用WSL 2,而不是以前的Hyper-V。 2、检查系统要求:系统最好是Windows 1…

UE4 C++联网RPC教程笔记(三)(第8~9集)完结

UE4 C联网RPC教程笔记&#xff08;三&#xff09;&#xff08;第8~9集&#xff09;完结 8. exe 后缀实现监听服务器9. C 实现监听服务器 8. exe 后缀实现监听服务器 前面我们通过蓝图节点实现了局域网连接的功能&#xff0c;实际上我们还可以给项目打包后生成的 .exe 文件创建…

【优选算法专栏】专题九:链表--------两两交换链表中的节点

本专栏内容为&#xff1a;算法学习专栏&#xff0c;分为优选算法专栏&#xff0c;贪心算法专栏&#xff0c;动态规划专栏以及递归&#xff0c;搜索与回溯算法专栏四部分。 通过本专栏的深入学习&#xff0c;你可以了解并掌握算法。 &#x1f493;博主csdn个人主页&#xff1a;小…

华清远见作业第四十天——Qt(第二天)

思维导图&#xff1a; 编程&#xff1a; 使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数 将登录按钮使用qt5版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断ui界面上输入的账号是否为…

智慧园区软件解决方案,园区运营管理系统(源码)

一、楼栋管理 1、园区信息&#xff1a;描述园区信息&#xff0c;有些规模较大的产业园区会存在A区&#xff0c;B区&#xff0c;C区。 2、楼栋信息&#xff1a;管理园区所有的楼栋&#xff0c;设有楼栋编号&#xff0c;所属园区&#xff0c;楼栋地址等。 3、房源信息&#xf…

JAVA并发编程之原子性、可见性与有序性

并发编程-原子性、可见性与有序性 一、CPU的可见性 1.1 缓存一致性问题的出现 CPU处理器在处理速度上&#xff0c;远胜于内存&#xff0c;主内存执行一次内存的读写操作&#xff0c;所需要的时间足够处理器去处理上百条指令。 为了弥补处理器与主内存处理能力之间的差距&am…