• JAVA【设计模式】策略模式


    一、定义

    在这里插入图片描述

    策略模式:指定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。

    二、示例:

    模拟场景:
    1、在本案例中我们模拟在购买商品时候使⽤的各种类型优惠券(满减、直减、折扣、n元购),这个场景⼏乎也是⼤家的⼀个⽇常购物省钱渠道,购买商品的时候都希望找⼀些优惠券,让购买的商品更加实惠。

    传统编码

    通过if判断,券的类型越多,if也就越多,代码冗余,臃肿

    package com.qf.design.behavior.strategy.tradition;
    
    public class CouponDiscountService {
    
        public double discountAmount(int type, double typeContent, double skuPrice, double typeExt){
            //1.直减券
            if (type==1){
                return skuPrice-typeContent;
            }
    
            //2.满减券
            if (type==2){
                if (skuPrice<typeExt) return skuPrice;
                else return skuPrice-typeContent;
            }
    
            //3.折扣券
            if (type==3){
                return skuPrice*typeContent;
            }
    
            //4.n元购
            if (type==4){
                return typeContent;
            }
    
            return 0D;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    package com.qf.design.behavior.strategy.tradition;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class ApiTest {
    
        private static  Logger logger= LoggerFactory.getLogger(ApiTest.class);
        public static void main(String[] args) {
            CouponDiscountService couponDiscountService=new CouponDiscountService();
            //1.直减券
            double desc = couponDiscountService.discountAmount(1, 23.5, 55.5, 0);
            logger.info("直减券:{}",desc);
            //3.折扣券
            double discount = couponDiscountService.discountAmount(3, 0.5, 800, 0);
            logger.info("折扣券:{}",discount);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    策略模式设计

    折扣接口

    package com.qf.design.behavior.strategy.design;
    
    import java.math.BigDecimal;
    
    public interface ICouponDiscount<T> {
    
        /**
         * 优惠券⾦额计算
         * @param couponInfo 券折扣信息;直减、满减、折扣、N元购
         * @param skuPrice sku⾦额
         * @return 优惠后⾦额
         */
        BigDecimal discountAmount(T couponInfo,BigDecimal skuPrice);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    满减

    package com.qf.design.behavior.strategy.design.impl;
    
    import com.qf.design.behavior.strategy.design.ICouponDiscount;
    
    import java.math.BigDecimal;
    import java.util.Map;
    
    /**
     * 满减
     */
    public class MJCouponDiscount implements ICouponDiscount<Map<String,String>> {
        @Override
        public BigDecimal discountAmount(Map<String, String> couponInfo, BigDecimal skuPrice) {
            String x = couponInfo.get("x");
            String o = couponInfo.get("n");
            // ⼩于商品⾦额条件的,直接返回商品原价
            if (skuPrice.compareTo(new BigDecimal(x)) < 0) return skuPrice;
            // 减去优惠⾦额判断
            BigDecimal discountAmount = skuPrice.subtract(new BigDecimal(0));
            if (discountAmount.compareTo(BigDecimal.ZERO) < 1) return
                    BigDecimal.ONE;
            return discountAmount;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    N元购

    package com.qf.design.behavior.strategy.design.impl;
    
    import com.qf.design.behavior.strategy.design.ICouponDiscount;
    
    import java.math.BigDecimal;
    
    public class NYGCouponDiscount implements ICouponDiscount<Double> {
        @Override
        public BigDecimal discountAmount(Double couponInfo, BigDecimal skuPrice) {
            return new BigDecimal(couponInfo);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    直减价

    package com.qf.design.behavior.strategy.design.impl;
    
    import com.qf.design.behavior.strategy.design.ICouponDiscount;
    
    import java.math.BigDecimal;
    
    public class ZJCouponDiscount implements ICouponDiscount<Double> {
        @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;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    折扣价

    package com.qf.design.behavior.strategy.design.impl;
    
    import com.qf.design.behavior.strategy.design.ICouponDiscount;
    
    import java.math.BigDecimal;
    
    public class ZKCouponDiscount implements ICouponDiscount<Double> {
        @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;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    策略控制类

    package com.qf.design.behavior.strategy.design;
    
    import java.math.BigDecimal;
    
    public class Context<T> {
        private ICouponDiscount<T> iCouponDiscount;
    
        public Context(ICouponDiscount<T> iCouponDiscoun){
            this.iCouponDiscount=iCouponDiscoun;
        }
    
        public BigDecimal discountAmount(T couponInfo,BigDecimal skuPrice){
            return iCouponDiscount.discountAmount(couponInfo,skuPrice);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    测试:ApiTest

    package com.qf.design.behavior.strategy.design;
    
    import java.math.BigDecimal;
    
    public class Context<T> {
        private ICouponDiscount<T> iCouponDiscount;
    
        public Context(ICouponDiscount<T> iCouponDiscoun){
            this.iCouponDiscount=iCouponDiscoun;
        }
    
        public BigDecimal discountAmount(T couponInfo,BigDecimal skuPrice){
            return iCouponDiscount.discountAmount(couponInfo,skuPrice);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    UML关系图

    在这里插入图片描述
    总结:
    以上的策略模式案例相对来说不并不复杂,主要的逻辑都是体现在关于不同种类优惠券的计算折扣策略上。结构相对来说也⽐较简单,在实际的开发中这样的设计模式也是⾮常常⽤的。另外这样的设计与命令模式、适配器模式结构相似,但是思路是有差异的。

    通过策略设计模式的使⽤可以把我们⽅法中的if语句优化掉,⼤量的if语句使⽤会让代码难以扩展,也不好维护,同时在后期遇到各种问题也很难维护。在使⽤这样的设计模式后可以很好的满⾜隔离性与和扩展性,对于不断新增的需求也⾮常⽅便承接。

  • 相关阅读:
    基于SpringCloud+redis+Springsecurity实现的微信小程序外卖系统
    JAVA编程规范之安全规约
    Nautilus Chain上线主网,为DeFi和流支付的未来构建基础
    ​软考-高级-信息系统项目管理师教程 第四版【第19章-配置与变更管理-思维导图】​
    Python每日一练(牛客数据分析篇新题库)——第31天:中位函数
    CentOS7.6升级到CentOS7.9并升级内核
    民宿管理系统应该怎么选择?民宿系统有哪些作用?
    关于js_节流的介绍和简单的使用
    现在游戏出海有多少优势?
    使用MyBatisPlus进行字段的自动填充
  • 原文地址:https://blog.csdn.net/cativen/article/details/126270037