首页 > 编程笔记 > Java笔记

使用策略模式实现电商多种促销优惠方案选择

马上要双11了,很多电商平台都会推出优惠活动。优惠策略有很多种,如领取优惠券抵扣、返现促销、拼团优惠、秒杀优惠等。下面我们使用策略模式来模拟实现电商中多种促销优惠方案的选择。

首先创建一个抽象策略角色 PromotionStrategy。
  1. /**
  2. * 促销策略抽象
  3. */
  4. public interface PromotionStrategy {
  5. void doPromotion();
  6. }
然后分别创建优惠券抵扣策略 CouponStrategy 类、返现促销策略 CashbackStrategy 类、拼团优惠策略 GroupBuyStrategy 类和无优惠策略 EmptyStrategy 类。

CouponStrategy 类的代码如下。
  1. public class CouponStrategy implements PromotionStrategy {
  2. public void doPromotion() {
  3. System.out.println("使用优惠券抵扣");
  4. }
  5. }
CashbackStrategy 类的代码如下。
  1. public class CashbackStrategy implements PromotionStrategy {
  2. public void doPromotion() {
  3. System.out.println("返现,直接打款到支付宝账号");
  4. }
  5. }
GroupBuyStrategy 类的代码如下。
  1. public class GroupBuyStrategy implements PromotionStrategy {
  2. public void doPromotion() {
  3. System.out.println("5人成团,可以优惠");
  4. }
  5. }
EmptyStrategy 类的代码如下。
  1. public class EmptyStrategy implements PromotionStrategy {
  2. public void doPromotion() {
  3. System.out.println("无优惠");
  4. }
  5. }
创建促销活动方案 PromotionActivity 类。
  1. public class PromotionActivity {
  2. private PromotionStrategy strategy;
  3.  
  4. public PromotionActivity(PromotionStrategy strategy) {
  5. this.strategy = strategy;
  6. }
  7.  
  8. public void execute() {
  9. strategy.doPromotion();
  10. }
  11. }
最后编写客户端测试代码。
  1. public class Test {
  2. public static void main(String[] args) {
  3. PromotionActivity activity618 = new PromotionActivity(new CouponStrategy());
  4. PromotionActivity activity1111 = new PromotionActivity(new CouponStrategy());
  5.  
  6. activity618.execute();
  7. activity1111.execute();
  8. }
  9. }
此时,可以发现上面这段客户端测试代码并不适用于实际的业务场景,因为我们做活动时往往要根据不同的需求对促销策略进行动态选择,并不会一次性执行多种优惠。

所以通常代码会这样写。
  1. public class Test {
  2. public static void main(String[] args) {
  3. PromotionActivity activity = null;
  4. String promotionKey = "COUPON";
  5. if (StringUtils.equals(promotionKey, "COUPON")) {
  6. activity = new PromotionActivity(new CouponStrategy());
  7. } else if (StringUtils.equals(promotionKey, "CASHBACK")) {
  8. activity = new PromotionActivity(new CashbackStrategy());
  9. }
  10. activity.execute();
  11. }
  12. }
这样改造之后,代码就满足了业务需求,客户可根据自己的需求选择不同的优惠策略。但是,经过一段时间的业务积累,促销活动会越来越多,程序员就开始经常加班,每次上活动之前就要通宵改代码,而且要做重复测试,判断逻辑可能也会变得越来越复杂。此时,我们就要思考代码是否需要重构。

回顾之前学过的设计模式,我们可以结合单例模式和简单工厂模式来优化这段代码。创建 PromotionStrategyFactory 类。
  1. public class PromotionStrategyFactory {
  2. private static Map<String, PromotionStrategy> PROMOTIONS = new HashMap<String, PromotionStrategy>();
  3.  
  4. static {
  5. PROMOTIONS.put(PromotionKey.COUPON, new CouponStrategy());
  6. PROMOTIONS.put(PromotionKey.CASHBACK, new CashbackStrategy());
  7. PROMOTIONS.put(PromotionKey.GROUPBUY, new GroupBuyStrategy());
  8. }
  9.  
  10. private static final PromotionStrategy EMPTY = new EmptyStrategy();
  11.  
  12. private PromotionStrategyFactory() {
  13. }
  14.  
  15. public static PromotionStrategy getPromotionStrategy(String promotionKey) {
  16. PromotionStrategy strategy = PROMOTIONS.get(promotionKey);
  17. return strategy == null ? EMPTY : strategy;
  18. }
  19.  
  20. private interface PromotionKey {
  21. String COUPON = "COUPON";
  22. String CASHBACK = "CASHBACK";
  23. String GROUPBUY = "GROUPBUY";
  24. }
  25.  
  26. public static Set<String> getPromotionKeys() {
  27. return PROMOTIONS.keySet();
  28. }
  29. }
这时客户端测试代码如下。
  1. public class Test {
  2. public static void main(String[] args) {
  3. PromotionStrategyFactory.getPromotionKeys();
  4. String promotionKey = "COUPON";
  5. PromotionStrategy promotionStrategy = PromotionStrategyFactory.getPromotionStrategy(promotionKey);
  6. promotionStrategy.doPromotion();
  7. }
  8. }
这样代码优化之后,每次上新活动都不会影响原来的代码逻辑,程序员的维护工作也变得轻松了。

所有教程

优秀文章