首页 > 编程笔记 > Java笔记

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

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

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

CouponStrategy 类的代码如下。
public class CouponStrategy implements PromotionStrategy {
    public void doPromotion() {
        System.out.println("使用优惠券抵扣");
    }
}
CashbackStrategy 类的代码如下。
public class CashbackStrategy implements PromotionStrategy {
    public void doPromotion() {
        System.out.println("返现,直接打款到支付宝账号");
    }
}
GroupBuyStrategy 类的代码如下。
public class GroupBuyStrategy implements PromotionStrategy {
    public void doPromotion() {
        System.out.println("5人成团,可以优惠");
    }
}
EmptyStrategy 类的代码如下。
public class EmptyStrategy implements PromotionStrategy {
    public void doPromotion() {
        System.out.println("无优惠");
    }
}
创建促销活动方案 PromotionActivity 类。
public class PromotionActivity {
    private PromotionStrategy strategy;

    public PromotionActivity(PromotionStrategy strategy) {
        this.strategy = strategy;
    }

    public void execute() {
        strategy.doPromotion();
    }
}
最后编写客户端测试代码。
public class Test {
    public static void main(String[] args) {
        PromotionActivity activity618 = new PromotionActivity(new CouponStrategy());
        PromotionActivity activity1111 = new PromotionActivity(new CouponStrategy());

        activity618.execute();
        activity1111.execute();
    }
}
此时,可以发现上面这段客户端测试代码并不适用于实际的业务场景,因为我们做活动时往往要根据不同的需求对促销策略进行动态选择,并不会一次性执行多种优惠。

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

回顾之前学过的设计模式,我们可以结合单例模式和简单工厂模式来优化这段代码。创建 PromotionStrategyFactory 类。
public class PromotionStrategyFactory {
    private static Map<String, PromotionStrategy> PROMOTIONS = new HashMap<String, PromotionStrategy>();

    static {
        PROMOTIONS.put(PromotionKey.COUPON, new CouponStrategy());
        PROMOTIONS.put(PromotionKey.CASHBACK, new CashbackStrategy());
        PROMOTIONS.put(PromotionKey.GROUPBUY, new GroupBuyStrategy());
    }

    private static final PromotionStrategy EMPTY = new EmptyStrategy();

    private PromotionStrategyFactory() {
    }

    public static PromotionStrategy getPromotionStrategy(String promotionKey) {
        PromotionStrategy strategy = PROMOTIONS.get(promotionKey);
        return strategy == null ? EMPTY : strategy;
    }

    private interface PromotionKey {
        String COUPON = "COUPON";
        String CASHBACK = "CASHBACK";
        String GROUPBUY = "GROUPBUY";
    }

    public static Set<String> getPromotionKeys() {
        return PROMOTIONS.keySet();
    }
}
这时客户端测试代码如下。
public class Test {
    public static void main(String[] args) {
        PromotionStrategyFactory.getPromotionKeys();
        String promotionKey = "COUPON";
        PromotionStrategy promotionStrategy = PromotionStrategyFactory.getPromotionStrategy(promotionKey);
        promotionStrategy.doPromotion();
    }
}
这样代码优化之后,每次上新活动都不会影响原来的代码逻辑,程序员的维护工作也变得轻松了。

所有教程

优秀文章