欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SpringBoot中使用策略模式

程序员文章站 2022-07-05 21:58:02
策略模式:定义一组算法,将每个算法都封装起来,相互之间可以互换。策略模式需要一个抽象算法接口,一组算法,一个容器类(Context)假设我们有一个场景:根据传值type的不同,调用不同的接口(加减乘除)抽象算法接口:public interface IZStrategy { /** * 计算 * @param a * @param b * @return */ BigDecimal doCalculate(BigDecima...

策略模式:定义一组算法,将每个算法都封装起来,相互之间可以互换。

策略模式需要一个抽象算法接口,一组算法,一个容器类(Context)

假设我们有一个场景:根据传值type的不同,调用不同的接口(加减乘除)

抽象算法接口:

public interface IZStrategy {
    /**
     * 计算
     * @param a
     * @param b
     * @return
     */
    BigDecimal doCalculate(BigDecimal a,BigDecimal b);
}

算法1:

@Slf4j
@Component
public class ZAddStrategy implements IZStrategy {

    @Override
    public BigDecimal doCalculate(final BigDecimal a,final BigDecimal b) {
        return a.add(b);
    }
}

算法2:

@Slf4j
@Component
public class ZSubstractStrategy implements IZStrategy {

    @Override
    public BigDecimal doCalculate(final BigDecimal a,final BigDecimal b) {
        return a.subtract(b);
    }

}

枚举类型:(方便调用)



    public enum ZStrategyEnum {
        /**
         * add
         */
        ADD_STRATEGY("1","zAddStrategy"),

        /**
         * substract
         */
        SUBSTRACT_STRATEGY("2","zSubstractStrategy");

        private String type;
        private String bean;

        private static final Map<String, ZStrategyEnum> Z_STRATEGY_MAP = new HashMap<>(values().length);

        static {
            for (final ZStrategyEnum zStrategy:values()) {
                Z_STRATEGY_MAP.put(zStrategy.getType(),zStrategy);
            }
        }

        ZStrategyEnum(String type, String bean){
            this.type = type;
            this.bean = bean;
        }

        public String getType() {
            return type;
        }

        public void setType(final String type) {
            this.type = type;
        }

        public String getBean() {
            return bean;
        }

        public void setBean(final String bean) {
            this.bean = bean;
        }

        /**
         * 根据传的type返回bean
         * @param type
         * @return
         */
        public static String getBeanByType(final String type){
            final ZStrategyEnum zStrategyEnum = Z_STRATEGY_MAP.get(type);
            return null != zStrategyEnum ? zStrategyEnum.getBean() : "";
        }

}

容器类(Context):


@Slf4j
@Service
public class ZStrategyContext {

    /**
     * 用线程安全的concurrentHashMap
     */
    private Map<String,IZStrategy> zStrategyMap = new ConcurrentHashMap<>();

    @Autowired
    private ZStrategyContext(final Map<String,IZStrategy> map){
        /**
         * 这个没理解过原因,只是在《设计模式之禅》当中看到过假如不clear会出现很多奇奇怪怪的bug的描述,印象害挺深刻
         */
        zStrategyMap.clear();
        map.forEach(this.zStrategyMap::put);
    }

    @SneakyThrows
    public IZStrategy getStrategy(final String type){
        if (null != type && !StringUtils.isBlank(type) && null != ZStrategyEnum.getBeanByType(type)){
            return zStrategyMap.get(ZStrategyEnum.getBeanByType(type));
        }else {
            log.info("未能查询到对应type");
            throw new Exception("a");
        }
    }
}

到此我们的策略模式就写完了。来看看具体实现

业务接口

public interface IModelService {
    BigDecimal cal(String type);
}

接口实现


@Service
public class ModelServiceImpl implements IModelService {

    @Autowired
    private ZStrategyContext zStrategyContext;

    @Override
    public BigDecimal cal(final String type) {
        BigDecimal val1 = BigDecimal.ZERO;
        BigDecimal val2 = BigDecimal.ZERO;
        return zStrategyContext.getStrategy(type).doCalculate(val1,val2);
    }
}

 

本文地址:https://blog.csdn.net/qq_38895905/article/details/107696654

相关标签: 设计模式