设计模式 | 策略模式介绍、使用案例、开源框架应用

目录

策略模式概念

策略模式使用案例

策略模式在开源框架中的应用


策略模式概念

  • 定义:定义了算法家族,分别封装起来,让他们之间可以相互调用,此模式让算法的变化不会影响到使用算法的用户。可以消除大量的if-else代码
  • 适用场景:系统有很多类,而它们的区别仅仅在于他们的行为不同;一个系统需要动态的在几种算法中选择一种。
  • 优点:符合开闭原则;避免了使用多重条件转移语句;确保算法的保密性和安全性;
  • 缺点:客户端必须知道所有的策略类,并且自行决定使用哪一个策略类;新增很多类;

策略模式使用案例

以电商系统的折扣模型来演示策略模式,淘淘购物网的活动折扣包含满减、返现、立减等。在使用策略模式前需要很多if-else代码来做优惠券类型判断,以做出扣减。使用策略模式的代码如下:

创建一个折扣父接口,它有一个打折方法

public interface PromotiionStrategy {
    void doPromotion();
}

创建具体活动类,继承父接口

//返现活动类
public class FanxianPromotiionStrategy implements PromotiionStrategy{
    @Override
    public void doPromotion() {
        System.out.println("返现促销,返回的金额存放到慕课网账户余额中");
    }
}

//立减活动类
public class LijianPromotiionStrategy implements PromotiionStrategy{
    @Override
    public void doPromotion() {
        System.out.println("立减促销,课程价格直接减去促销价格");
    }
}

//满减活动类
public class ManjianPromotiionStrategy implements PromotiionStrategy{
    @Override
    public void doPromotion() {
        System.out.println("满减促销,满200减20元");

    }
}

//不参与活动类
public class NonPromotiionStrategy implements PromotiionStrategy{
    @Override
    public void doPromotion() {
        System.out.println("无优惠");
    }
}

创建活动调用类,关联折扣父接口,executePromotiionStrategy方法调用父接口的打折方法。

public class PromotionActivity {
    public PromotionActivity(PromotiionStrategy promotiionStrategy) {
        this.promotiionStrategy = promotiionStrategy;
    }
    private PromotiionStrategy promotiionStrategy;
    public void executePromotiionStrategy(){
        promotiionStrategy.doPromotion();
    }

}

创建测试类

 public static void main(String[] args) {
        String type = "lijian";
        PromotionActivity promotionActivity = null;
        if(type.equals("lijian")){
            promotionActivity = new PromotionActivity(new LijianPromotiionStrategy());

        }else if(type.equals("manjian")){
            promotionActivity = new PromotionActivity(new ManjianPromotiionStrategy());

        }else if(type.equals("fanxian")){
            promotionActivity = new PromotionActivity(new FanxianPromotiionStrategy());

        }
        promotionActivity.executePromotiionStrategy();

    }

输出:立减促销,课程价格直接减去促销价格

可以看到使用了策略模式后减少了在扣减时的if-else判断,但是在类型判断时仍然有if-else判断,所以在使用策略模式时推荐搭配工厂模式,具体实现如下

新增策略工厂类

public class PromotiionStrategyFactory {
    private static Map MAP_INFO = new HashMap<>();
    public static String LIJIAN_KEY = "lijian";
    public static String MANJIAN_KEY = "manjian";
    public static String FANXIAN_KEY = "fanxian";

    static {
        MAP_INFO.put(LIJIAN_KEY,new LijianPromotiionStrategy());
        MAP_INFO.put(MANJIAN_KEY,new ManjianPromotiionStrategy());
        MAP_INFO.put(FANXIAN_KEY,new FanxianPromotiionStrategy());

    }
    private static final PromotiionStrategy NON_PROMOTION = new NonPromotiionStrategy();

    public PromotiionStrategyFactory() {
    }
    public static PromotiionStrategy getPromotiionStrategy(String key){
        PromotiionStrategy result = MAP_INFO.get(key);
        return  result == null ? NON_PROMOTION:result;
    }

}

新建测试方法

 public static void main(String[] args) {
        String type = "manjian";
        PromotionActivity promotionActivity = new PromotionActivity(PromotiionStrategyFactory.getPromotiionStrategy(type));
        promotionActivity.executePromotiionStrategy();

    }

打印输出:满减促销,满200减20元

可以看到使用了策略模式后逻辑变得很清晰,且很容易拓展。如果想拓展一种新的促销时客户端只需要在调用打折方法时同时传入约定好的类型即可,后段处理逻辑中新增一个促销类,并完善工厂方法的类型池。符合开闭原则。

类图如下:

设计模式 | 策略模式介绍、使用案例、开源框架应用_第1张图片

策略模式在开源框架中的应用

  • spring框架中的InstantiationStrategy类,用作类实例化
  • org.springframework.core.io.Resource类,用作资源加载

 

 

 

 

你可能感兴趣的:(设计模式)