如何用Spring实现策略模式

引言

在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。

经典的商城打折生活用例,这种场景最适合用策略模式,客户将自己的身份告诉商城,商城根据客户的类型给予不同的优惠策略,普通用户不打折,会员8折,内部员工三折。如果不用设计模式用if...else语句实现起来也就几行代码的事情,不过这种实现方式看起来不太优雅,没有体现设计思维,所以我们尝试用Spring机制来实现策略模式吧。

我们来看类图。

如何用Spring实现策略模式_第1张图片
image.png

IDiscountStrategy是折扣接口

*StrategyImpl这些类实现的是不同的客户类型使用的不同的折扣策略。

StrateType是自定义折扣类型注解。

StrategyHandlerComponent这个类是Spring的组件类,通过它获取所有的折扣类,将这些折扣类存放在一个线程安全的HashMap中,key存储的是DiscountEnum枚举中的name();
一句话表达就是将折扣类和折扣类型关键字建立起mapping隐射。


public enum  DiscountEnum {

  /**
   * 普通客户
   */
  NOMARL,

  /**
   * 会员
   */
  MEMBER,


  EMPLOYEE;
}

最后就是客户调用步骤

@Autowired
    StrategyHandlerComponent strategyHandlerComponet;

    @GetMapping("/strategy")
    public String strategy(String strategy) {
        ConcurrentHashMap map=strategyHandlerComponet.getDiscountStrategyConcurrentHashMap();
        if(map.keySet().contains(strategy)){
            return  "外星人不能享受折扣优惠";
        }
        return map.get(strategy).discount();
    }

核心代码StrategyHandlerComponent

package com.sgm.ossp.order.strategy;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

import java.util.concurrent.ConcurrentHashMap;

@Component
public class StrategyHandlerComponent implements  BeanPostProcessor {

    private ConcurrentHashMap discountStrategyConcurrentHashMap=new ConcurrentHashMap<>();

    public ConcurrentHashMap getDiscountStrategyConcurrentHashMap() {
        return discountStrategyConcurrentHashMap;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        Class aClass=bean.getClass();
        if(aClass.isAnnotationPresent(StrateType.class)&&isInstanceOfDiscountStrategy(aClass)){
            StrateType strateType= (StrateType) aClass.getAnnotation(StrateType.class);
            System.out.println("输出bean......"+bean.getClass().getName());
            discountStrategyConcurrentHashMap.put(strateType.value().name(),(IDiscountStrategy) bean);
        }
        return bean;
    }


    //类似于InitializingBean.afterPropertiesSet()
   //这里面获取所有的折扣实现类
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    private boolean isInstanceOfDiscountStrategy( Class aClass){
        try {
            return  (aClass.newInstance() instanceof  IDiscountStrategy);
        } catch (Exception e) {
            return  false;
        }
    }


}

部署到Tomcat之后以get请求示例:{protocol}://{ip}:{port}/strategy?strategy={枚举类的name()}

你可能感兴趣的:(如何用Spring实现策略模式)