策略模式(strategy)

一、简单介绍

策略这个词应该怎么理解,打个比方说,我们出门的时候会选择不同的出行方式,比如骑自行车、坐公交、坐火车、坐飞机、坐火箭等等,这些出行方式,每一种都是一个策略。

再比如我们去逛商场,商场现在正在搞活动,有打折的、有满减的、有返利的等等,其实不管商场如何进行促销,说到底都是一些算法,这些算法本身只是一种策略,并且这些算法是随时都可能互相替换的,比如针对同一件商品,今天打八折、明天满100减30,这些策略间是可以互换的。

有很多时候我们会使用if else 来解决这个问题

if(type.equals("A")){
    // do func A
}else if(type.equals("B")){
    // do func B
}else if(type.equals("C")){
    // do func C
}else[
   //...
}

这种 if-else 或者 switch-case 代码在每个分支都会判断分支类型,然后执行不同的方法获取结果,当代码分支比较少并且确定不会增加时,使用这种方式也是完全 ok 的,但是当分支比较多,并且后面可能会增加分支判断条件时,这种方式就违反了单一职责和开闭原则,因此对于我们开发工作中遇到这种情况,就是自然的考虑能不能用策略模式去重写,将代码和业务逻辑解耦,这样才有利于后续的维护工作。
比如,上面的if-else 我们可以优化为下面的代码

策略抽象接口

public interface IStrategy {
    void doSomething();
}

策略A

public class StrategyA implements IStrategy {
    @Override
    public void doSomething() {
        System.out.println("A");
    }
}

策略B

public class StrategyB implements IStrategy {
    @Override
    public void doSomething() {
        System.out.println("B");
    }
}

策略C

public class StrategyC implements IStrategy {
    @Override
    public void doSomething() {
        System.out.println("C");
    }
}

工厂

public class SimpleStrategyFactory {

    public static final String STRATEGY_A = "A";
    public static final String STRATEGY_B = "B";
    public static final String STRATEGY_C = "C";
    public static final String STRATEGY_DUFAULT = "A";

    private static Map<String, IStrategy> StrategyMap = new ConcurrentHashMap<>();
    static {
        StrategyMap.put(STRATEGY_A,new StrategyA());
        StrategyMap.put(STRATEGY_B,new StrategyB());
        StrategyMap.put(STRATEGY_C,new StrategyC());
    }

    public static IStrategy get(String key){
        if(!StrategyMap.containsKey(key)){
            return StrategyMap.get(STRATEGY_DUFAULT);
        }
        return StrategyMap.get(key);
    }
}

测试类

public class StrategyTest {
    public static void main(String[] args) {
        IStrategy strategy = SimpleStrategyFactory.get("A");
        strategy.doSomething();
    }
}

类结构图

在这里插入图片描述

场景二:商场促销活动

促销策略接口 IStrategy

public interface IStrategy {
    void discount();
}

返现策略类

public class CashbackStrategy implements IStrategy {
    public void discount() {
        System.out.println("返现促销");
    }
}

优惠券策略类

public class CouponStrategy implements IStrategy {
    public void discount() {
        System.out.println("商品的价格直接减优惠券面值抵扣");
    }
}

无优惠的策略类

public class EmptyStrategy implements IStrategy {
    public void discount() {
        System.out.println("无促销活动");
    }
}

满减策略类

public class FullMinusStrategy implements IStrategy {
    public void discount() {
        System.out.println("满500,减100活动");
    }
}

策略工厂类

public class PromotionStrategyFactory {
    private static Map<String, IStrategy> PROMOTION_STRATEGY_MAP = new HashMap<String, IStrategy>();
    static {
        PROMOTION_STRATEGY_MAP.put(PromotionKey.COUPON,new CouponStrategy());
        PROMOTION_STRATEGY_MAP.put(PromotionKey.CASHBACK,new CashbackStrategy());
        PROMOTION_STRATEGY_MAP.put(PromotionKey.FULLMINUS,new FullMinusStrategy());
    }

    private static final IStrategy NON_PROMOTION = new EmptyStrategy();

    private PromotionStrategyFactory(){}

    public static IStrategy getPromotionStrategy(String promotionKey){
        IStrategy promotionStrategy = PROMOTION_STRATEGY_MAP.get(promotionKey);
        return promotionStrategy == null ? NON_PROMOTION : promotionStrategy;
    }

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

测试类

public class StrategyTest {
    public static void main(String[] args) {
        IStrategy strategy = PromotionStrategyFactory.getPromotionStrategy("FULLMINUS");
        strategy.discount();
    }
}

运行结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值