写点什么

策略模式怎么玩?

用户头像
卢卡多多
关注
发布于: 2021 年 06 月 13 日
策略模式怎么玩?

策略

策略,即是我们在生活中面对一件事的多种做法,比如我要去北京,通常可以做火车,高铁,拼车等,或者自驾也可以,一个目标多种实现,放到业务中可能就有很多分支,如何将这些分支实例化,拒绝 if..else,这次带了干货哈哈😄


最近更新的文章类型比较杂,其实就是想拓宽一下自己的知识体系,作为设计模式,也是我们作为项目研发人员在考虑产品迭代的过程中就需要想到的,比如现在支付方式,你开一个文具店,支付的场景分为现金,银行卡,以及扫码支付,扫码有可以分为微信,支付宝,银联等支付方式,现在有比如新兴的优惠券满减,活动,以及免单抽奖等,这些都需要动态的记录支付方式,一来二去的,这个支付业务的树就越来越丰富, 难道我们就一直 if/else 下去吗?


不,我们不能够

策略模式

策略,即是战略,为了实现某一个场景下,抽象出的多种实现方式,这些方式的控制与实现就是我们今天要聊的策略模式。


可能没有具体的场景,理解起来比较困难,比如你自己的身份,面对不同的人,你的身份也会随之变化,称呼也会变化;


比如面对我的爷爷, 我会说爷爷好,身体怎么样了。对我的妈妈, 老妈好啊,最近家里可好,。。。。。


针对的对象不同,结果也是不同的;


这次我们就准备开始定制场景,开干;

场景:

你在京东买东西,一般可以商品的优惠,优惠类型分为多种,可以分为满减(满 200 减 20),直减,折扣劵(8.8),N 元购,类型,其中优惠类型就可以作为我们实现优惠的多种方式,


刚毕业的写法:


public class CouponDiscountService {
public double discountAmount(int type, double typeContent, double skuPrice, double typeExt) { // 1. 直减券 if (1 == type) { return skuPrice - typeContent; } // 2. 满减券 if (2 == type) { if (skuPrice < typeExt) return skuPrice; return skuPrice - typeContent; } // 3. 折扣券 if (3 == type) { return skuPrice * typeContent; } // 4. n元购 if (4 == type) { return typeContent; } return 0D; }
}
复制代码


此方法是我们常用的匹配方法,用于做小范围的匹配,规定枚举值进行分类,然后分别实现,但是这样代码的耦合性,和可维护性会大大下降,可读性也越来越差,

策略模式教你怎么玩

定制具体的优惠方法,然后开展实现类,实现类就是多种策略的实现,其中我们要用到泛型方法用作公共接口的入参表示;


public interface ICouponDiscount<T> {
/** * 优惠券金额计算 * @param couponInfo 券折扣信息;直减、满减、折扣、N元购 * @param skuPrice sku金额 * @return 优惠后金额 */ BigDecimal discountAmount(T couponInfo, BigDecimal skuPrice);
}
复制代码


定制化的接口,分为 标准的优惠类型 T ,以及商品的原价,返回商品优惠后的价格,

优惠类型实现

满减

通常说的满减,当满金额之后,减去加个,如果不符合会返回原来的价格,(满 200 减 20)


public class MJCouponDiscount implements ICouponDiscount<Map<String,String>>  {
/** * 满减计算 * 1. 判断满足x元后-n元,否则不减 * 2. 最低支付金额1元 */ public BigDecimal discountAmount(Map<String,String> couponInfo, BigDecimal skuPrice) { //当前的设定价格是满200减20 String x = couponInfo.get("x"); String o = couponInfo.get("o");
// 小于商品金额条件的,直接返回商品原价 if (skuPrice.compareTo(new BigDecimal(x)) < 0) return skuPrice; // 减去优惠金额判断 BigDecimal discountAmount = skuPrice.subtract(new BigDecimal(o)); if (discountAmount.compareTo(BigDecimal.ZERO) < 1) return BigDecimal.ONE;
return discountAmount; }}
复制代码


很多人对 compareTo 这个接口可能不太了解,我这里做个简单的 demo


public class Test {     public static void main(String args[]) {        String str1 = "Strings";        String str2 = "Strings";        String str3 = "Strings123";         int result = str1.compareTo( str2 );        System.out.println(result);         //0        result = str2.compareTo( str3 );        System.out.println(result);        //-3        result = str3.compareTo( str1 );        System.out.println(result);        //3    }}
复制代码


compareTo 主要用于对象之间的比较,


  • 如果参数字符串等于此字符串,则返回值 0;

  • 如果此字符串小于字符串参数,则返回一个小于 0 的值;

  • 如果此字符串大于字符串参数,则返回一个大于 0 的值。

直减

ublic class ZJCouponDiscount implements ICouponDiscount<Double>  {
/** * 直减计算 * 1. 使用商品价格减去优惠价格 * 2. 最低支付金额1元 */ 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; }
}
复制代码


####折扣劵


public class ZKCouponDiscount implements ICouponDiscount<Double> {

/** * 折扣计算 * 1. 使用商品价格乘以折扣比例,为最后支付金额 * 2. 保留两位小数 * 3. 最低支付金额1元 */ 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; }
}
复制代码

N 元购

public class NYGCouponDiscount implements ICouponDiscount<Double> {
/** * n元购购买 * 1. 无论原价多少钱都固定金额购买 */ public BigDecimal discountAmount(Double couponInfo, BigDecimal skuPrice) { return new BigDecimal(couponInfo); }
}
复制代码

总结

对于策略模式,主要是根据多种实现方式抽象出标准的接口,利用接口与实现类的关系,多种实现,不再依赖于单纯的 if。。else 的单值匹配,完成任务,上方的代码来自于我今晚刚到的新货,小傅哥的《重学 Java 设计模式》,感觉这个优惠券的类型对标策略模式更加生动形象,其实这只是简单的让你理解策略模式,在真正的项目中,可能是工厂加上代理加上策略模式来实现 AOP 切面的场景,


一切技术需要有实际业务的支撑才能发挥价值,所以都要考虑具体的场景去实现,好了,今天的分享就到这里了,


我是卢卡,要早睡点了,大家看完记得点赞 加评论哦,晚安好梦。

发布于: 2021 年 06 月 13 日阅读数: 32
用户头像

卢卡多多

关注

还未添加个人签名 2020.04.12 加入

还未添加个人简介

评论

发布
暂无评论
策略模式怎么玩?