[Spring源码阅读]如何通过配置文件管理策略

策略模式的基本结构

策略,可以简单理解为解决某个问题的具体方法。

当一个问题的解决方法有多种,并且需要根据具体场景灵活替换时,我们可以使用策略模式。

策略模式的概念不多说,借网上的图来描述一下:

 策略的实现依赖于具体的业务场景,这个没什么好说的;但是策略的管理是一种比较通用的方式,也是本文探讨的主要内容。

以上图为例,Context维护着策略的实现,executeState接口屏蔽了这种实现。除了提供获取策略的途径外,Context还需要做下面两件事:

1. 策略收集。对于Context来说,策略交给他管理后,他需要知道一共有哪些策略。

2. 策略配置。即当前生效的策略时哪一个。(或者给executeStrategy加个参数policyName,客户端直接传进来,可以参考下面的案例)

在平时的开发过程中,如果我们使用Spring或者相关的容器框架,可以考虑把所有的策略放到容器中。所以策略管理,可以简单地实现为:将所有实现Stategy接口的类从容器中取出来,放入Context中。

示例代码如下:

策略接口

public interface Strategy {

    int doOperation();
}

实现类

@Component
public class StrategyA implements Strategy{
    @Override
    public int doOperation() {
        return 1;
    }
}
@Component
public class StrategyB implements Strategy{
    @Override
    public int doOperation() {
        return 2;
    }
}

Context

@Component
public class StrategyContext {

    @Autowired
    private ApplicationContext applicationContext;

    private Map<String, Strategy> strategyMap = new HashMap<>();

    @PostConstruct
    public void init() {
        Map<String, Strategy> impls = applicationContext.getBeansOfType(Strategy.class);
        for (String key : impls.keySet()) {
            strategyMap.put(key, impls.get(key));
        }
    }

    public Strategy get(String policyName) {
        return strategyMap.get(policyName);
    }
}

问题点

上述方法的问题点在于,针对每一组策略的Context,都需通过硬编码的方式来管理。

什么意思呢?一个项目中可能不止有一个策略。比如

Strategy1策略有对应的实现StrategyA、StrategyB、StrategyC;

Strategy2有对应的实现StrategyD、StrategyE、StrategyF。

当需要做成策略的功能点很多时,这个时候就需要写很多个init方法,维护很多个strategyMapt,出现了很多的冗余代码。

Spring是如何解决这个问题的

我们以DispatchServlet为例

 DispatcherServlet初始化的时候,会调用initStrategies方法

 以HandlerMapping为例,通过getDefaultStrategies获取到HandlerMapping所有的实例

 getDefaultStrategies具体实现

 配置文件的全貌

配置文件中的每一个键值对代表一个策略组。key是策略接口,value是策略实现的集合。

 后面逻辑就很清晰了,通过key(策略)获取到values(策略实现)后,创建对应的策略实现。

 如何实际运用

上述案例中的key,value是对应策略的全路径。但对于我们开发者来说,在实际项目中不必照搬Spring的所有实现。

比如key可以设置为策略组的名称,value设置为策略实现的名称。获取策略的时候也不用去创建策略,可以兼容之前的做法,直接通过名称去Spring容器中取。

这种方式确实可以减少一些重复代码,但付出的代价是,每次获取策略的时候,需要额外提供一个策略组的名称。

总体看来,只能说是有利有弊吧。但如果开发构建大型系统,策略组特别多的话,这种方式还是很有必要的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值