定义
-
是一种行为设计模式, 它能让你定义一系列算法实现, 并将每种实现分别放入独立的类中, 以使算法的对象能够相互替换
类图
实现方式1
- 目前日常开发中常用的一种方式,快递路由的订阅回调接口为例
@Component
public class RouteNoticeCalculatorFactory implements ApplicationContextAware {
/**
* 维护 shippingKey 与 具体实现bean 映射关系
*/
private final Map<String, RouteNoticeCalculatorStrategy> routeNoticeCalculatorStrategyMap = new ConcurrentHashMap<>(16);
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
Map<String, RouteNoticeCalculatorStrategy> beans = applicationContext.getBeansOfType(RouteNoticeCalculatorStrategy.class);
for (Entry<String, RouteNoticeCalculatorStrategy> stringRouteNoticeCalculatorStrategyEntry : beans.entrySet()) {
RouteNoticeCalculatorStrategy routeNoticeCalculatorStrategy = stringRouteNoticeCalculatorStrategyEntry.getValue();
routeNoticeCalculatorStrategyMap.put(routeNoticeCalculatorStrategy.getShippingKey().name(), routeNoticeCalculatorStrategy);
}
}
/**
* 路由回调入口
*
* @param shippingKey shippingKey
* @param parameterMap 请求参数
* @return 结果
*/
public Object calculate(String shippingKey,Map<String,String[]> parameterMap){
Assert.hasText(shippingKey,"入参不合法,缺少shippingKey!");
LoggerMessageUtil.info(String.format("%s parameterMap:%s", shippingKey, JsonUtil.toJsonString(parameterMap)));
RouteNoticeCalculatorStrategy routeNoticeCalculatorStrategy = routeNoticeCalculatorStrategyMap.get(shippingKey);
Assert.notNull(routeNoticeCalculatorStrategy, ShippingKeyEnum.valueOf(shippingKey).name()+"路由回调接口还未实现!");
Object response = routeNoticeCalculatorStrategy.calculate(parameterMap);
LoggerMessageUtil.info(String.format("%s parameterMap:%s response:%s", shippingKey, JsonUtil.toJsonString(parameterMap),response.toString()));
return response;
}
}
实现方式2
demo
-
基于最小插件系统 spring-plugin 实现
-
项目pom.xml中引入
<dependency>
<groupId>org.springframework.plugin</groupId>
<artifactId>spring-plugin-core</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
源码分析
-
从哪里当做源码入口去看?
- @EnablePluginRegistries 注解
-
Bean是如何注册的?
-
org.springframework.plugin.core.config.PluginRegistriesBeanDefinitionRegistrar
-
-
核心接口
-
plugin的容器:org.springframework.plugin.core.PluginRegistry
-
-
注意点
- 可以加上 @Order 注解排序策略的实现
- 业务实现上注入的名字一定是 接口名 + Registry,除非加了@Qualifier注解
String beanName = annotation == null //
? StringUtils.uncapitalize(type.getSimpleName() + "Registry") //
: annotation.value();
一点思考
-
真正掌握不同设计模式的使用场景,切勿滥用
-
尝试学会并习惯去看英文文档学习(包括解决一些问题)
-
看源码,先简后难,先整体后局部,带着问题去看效果更佳
-
关于分享,费曼学习法