type
status
date
slug
summary
tags
category
icon
password
一、定义

策略模式:指定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。
二、示例:
模拟场景: 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; } } 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); } }
策略模式设计
折扣接口
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); }
满减
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; } }
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); } }
直减价
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; } }
折扣价
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; } }
策略控制类
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); } }
测试:
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); } }
UML关系图

总结: 以上的策略模式案例相对来说不并不复杂,主要的逻辑都是体现在关于不同种类优惠券的计算折扣策略上。结构相对来说也⽐较简单,在实际的开发中
这样的设计模式也是⾮常常⽤
的。另外这样的
设计与命令模式、适配器模式结构
相似,但是思路是有差异的。
通过策略设计模式的使⽤可以把我们⽅法中的if语句优化掉,⼤量的if语句使⽤会让代码难以扩展,也不好维护,同时在后期遇到各种问题也很难维护。在使⽤这样的设计模式后可以很好的满⾜隔离性与和扩展性,对于不断新增的需求也⾮常⽅便承接。
- 作者:程序员小舟
- 链接:https://codezhou.top/article/JAVA%E3%80%90%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%91%E7%AD%96%E7%95%A5%E6%A8%A1%E5%BC%8F
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
相关文章