使用策略模型重构电商优惠和支付场景可能,比如领券抵扣,返现促销,团购优惠等。下面代码用来模拟,先创建一个促销策略的抽象PromotionStrategy。/***促销策略抽象*由Tom创建。*/publicinterfaceIPromotionStrategy{voiddoPromotion();}然后创建抵扣券策略CouponStrategy类、返现促销策略CashbackStrategy类、团购优惠策略GroupbuyStrategy类和无优惠策略EmptyStrategy类。CouponStrategy类的代码如下。publicclassCouponStrategyimplementsIPromotionStrategy{publicvoiddoPromotion(){System.out.println("使用优惠券抵扣");}}CashbackStrategy类的代码如下。publicclassCashbackStrategyimplementsIPromotionStrategy{publicvoiddoPromotion(){System.out.println("返现,直接支付到支付宝账户");}}GroupbuyStrategy类的代码如下。publicclassGroupbuyStrategyimplementsIPromotionStrategy{publicvoiddoPromotion(){System.out.println("5人成团,有优惠");}}EmptyStrategy类的代码如下。publicclassEmptyStrategyimplementsIPromotionStrategy{publicvoiddoPromotion(){System.out.println("无折扣");}}然后创建促销活动计划PromotionActivity类。publicclassPromotionActivity{privateIPromotionStrategy策略;publicPromotionActivity(IPromotionStrategy策略){this.strategy=strategy;}publicvoidexecute(){strategy.doPromotion();}}最后写客户端测试代码。publicstaticvoidmain(String[]args){PromotionActivityactivity618=newPromotionActivity(newCouponStrategy());PromotionActivityactivity1111=newPromotionActivity(newCashbackStrategy());activity618.execute();activity1111.execute();,小伙伴们会发现,如果将上面的客户端测试代码放到实际的业务场景中,其实并不实用。因为我们在做活动的时候,往往要根据不同的需求动态选择促销策略,不会一次实施多种折扣。所以代码一般都是这样写的。publicstaticvoidmain(String[]args){PromotionActivitypromotionActivity=null;StringpromotionKey="优惠券";if(StringUtils.equals(promotionKey,"COUPON")){promotionActivity=newPromotionActivity(newCouponStrategy());}elseif(StringUtils.equals(promotionKey,"CASHBACK")){promotionActivity=newPromotionActivity(newCashbackStrategy());}//......promotionActivity.execute();}经过这样的改造,代码满足了业务需求,客户可以根据需要选择不同的优惠策略。不过,经过一段时间的业务积累,促销活动会越来越多。于是,程序员们开始频繁加班,每次活动前都要通宵改代码,还要反复测试,判断逻辑可能会越来越复杂。此时,我们不得不思考代码是否需要重构。回顾一下我们之前学过的设计模式,我们应该如何优化这段代码呢?其实PromotionStrategyFactory类可以结合单例模式和简单工厂模式来创建。publicclassPromotionStrategyFacory{privatestaticMapPROMOTIONS=newHashMap();static{PROMOTIONS.put(PromotionKey.COUPON,newCouponStrategy());PROMOTIONS.put(PromotionKey.CASHBACK,newCashbackStrategy());PROMOTIONS.put(PromotionKey.GROUPBUY,newGroupbuyStrategy());}privatestaticfinalIPromotionStrategyEMPTY=newEmptyStrategy();privatePromotionStrategyFacory(){}publicstaticIPromotionStrategygetPromotionStrategy(StringpromotionKey){IPromotionStrategystrategy=PROMOTIONS.get(promotionKey);返回策略==null?空:策略;}privateinterfacePromotionKey{StringCOUPON="COUPON";字符串现金返还=“现金返还”;StringGROUPBUY="GROUPBUY";}publicstaticSetgetPromotionKeys(){returnPROMOTIONS.keySet();}}此时,客户端测试代码如下。publicstaticvoidmain(String[]args){PromotionStrategyFacory.getPromotionKeys();StringpromotionKey="优惠券";IPromotionStrategypromotionStrategy=PromotionStrategyFacory.getPromotionStrategy(promotionKey);促销策略.doPromotion();也变得容易了。每一个新的活动都不会影响原来的代码逻辑。2 使用策略模式重构支付方式选择场景为了加深对策略模式的理解,再举一个案例。相信大家都用过支付宝、微信支付、银联和京东白条。一个常见的应用场景就是大家在下单的时候会提示选择支付方式。如果用户不选择,系统将默认推荐的支付方式。沉降。看下图所示的类图,我们使用策略模式来模拟这个业务场景。首先创建Payment抽象类,定义支付规范和支付逻辑,代码如下。importcom.tom.pattern.strategy.pay.PayState;/***支付渠道*由Tom创建。*/publicabstractclassPayment{publicabstractStringgetName();//通用逻辑放到抽象类中实现publicMsgResultpay(Stringuid,doubleamount){//余额是否充足if(queryBalance(uid)strategy=newHashMap();static{strategy.put(ALI_PAY,newAliPay());strategy.put(JD_PAY,newJDPay());strategy.put(微信支付,新微信支付());strategy.put(UNION_PAY,newUnionPay());}publicstaticPaymentget(StringpayKey){if(!strategy.containsKey(payKey)){returnstrategy.get(DEFAULT_PAY);}返回strategy.get(payKey);}}创建订单订单类。importcom.tom.pattern.strategy.pay.payport.PayStrategy;importcom.tom.pattern.strategy.pay.payport.Payment;/***由Tom创建。*/publicclassOrder{privateStringuid;私有字符串orderId;私人双倍金额;publicOrder(Stringuid,StringorderId,doubleamount){this.uid=uid;this.orderId=orderId;this.amount=金额;}publicMsgResultpay(){returnpay(PayStrategy.DEFAULT_PAY);}publicMsgResultpay(StringpayKey){Paymentpayment=PayStrategy.get(payKey);System.out.println("欢迎光临"+payment.getName());System.out.println("交易金额为"+amount+",开始扣减");返回payment.pay(uid,amount);}}最后,编写客户端测试代码。publicstaticvoidmain(String[]args){Orderorder=newOrder("1","2020031401000323",324.5);System.out.println(order.pay(PayStrategy.ALI_PAY));}运行结果如下图所示。通过常见业务场景的例子,希望小伙伴们能够对策略模型有更深入的了解。关注微信公众号『汤姆炸弹架构』回复“设计模式”获取完整源码。【推荐】汤姆炸弹架构:30个设计模式实战案例(附源码),挑战60W年薪不是梦技术在于分享,我分享我的快乐!如果本文对您有帮助,请关注并点赞;有什么建议也可以留言或私信。您的支持是我坚持创作的动力。关注微信公众号“汤姆炸弹建筑”,获取更多技术干货!