需求:根据策略对用户展示门槛信息,本次优化直接跳过常用的优化方案,直接给出最终的优化方案,并且后续可以完全复用策略工具类,实现快速使用策略模板处理。
演化一
List<ThresholdInfo> thresholdInfos = new ArrayList<>();
thresholdInfoConfigs.forEach(thresholdInfoConfig -> {
ThresholdInfo thresholdInfo = new ThresholdInfo();
thresholdInfo.setThresholdTitle(thresholdInfoConfig.getTaskTitle());
thresholdInfo.setThresholdDesc(thresholdInfoConfig.getThresholdDesc());
thresholdInfo.setThresholdIcon(thresholdInfoConfig.getIconUrl());
thresholdInfo.setBtnLink(thresholdInfoConfig.getBtnLink());
if (1 == thresholdInfoConfig.getTaskType()) {
// do anything (30天内无责任客诉)
} else if (2 == thresholdInfoConfig.getTaskType()) {
// do anything (三五证是否齐全)
}
thresholdInfos.add(thresholdInfo);
});
跳过策略优化,直接最终优化版本:
1、定义一个注解接口,这个是标识策略的
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Component
public @interface StrategyFlag {
/**
* 关键字
*
* @return {@link String}
*/
String value();
/**
* 场景(用来区分不同场景下value相同的情况)
*
* @return {@link String}
*/
String scene() default "";
/**
* 描述
*
* @return {@link String}
*/
String desc() default "";
}
2、在定义一个注解标识执行的方法
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface StrategyHandler {}
3、实现策略模式工具类,支持异步和同步两种方式
@Configuration
public class StrategyConfig<T, R> implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Bean
public CommonStrategy<T, R> commonStrategy() {
final Map<String, Object> strategyClass = applicationContext.getBeansWithAnnotation(StrategyFlag.class);
Map<String, Function<T, R>> strategyHandles = new HashMap<>();
for (Object x : strategyClass.values()) {
final String flag = x.getClass().getAnnotation(StrategyFlag.class).scene()
+ x.getClass().getAnnotation(StrategyFlag.class).value();
for (Method method : x.getClass().getMethods()) {
if (method.isAnnotationPresent(StrategyHandler.class)) {
strategyHandles.put(flag, context -> {
try {
return (R)method.invoke(x, context);
} catch (Exception e) {
throw new RuntimeException(e);
}
});
break;
}
}
}
return (flag, scene, context) -> strategyHandles.get(scene + flag).apply(context);
}
@Bean
public CommonFutureStrategy<T, R> commonFutureStrategy() {
final Map<String, Object> strategyClass = applicationContext.getBeansWithAnnotation(StrategyFlag.class);
Map<String, Function<T, CompletableFuture<R>>> strategyHandles = new HashMap<>();
for (Object x : strategyClass.values()) {
final String flag = x.getClass().getAnnotation(StrategyFlag.class).scene()
+ x.getClass().getAnnotation(StrategyFlag.class).value();
for (Method method : x.getClass().getMethods()) {
if (method.isAnnotationPresent(StrategyHandler.class)) {
strategyHandles.put(flag, context -> CompletableFuture.supplyAsync(() -> {
try {
return (R)method.invoke(x, context);
} catch (Exception e) {
throw new RuntimeException(e);
}
}, applicationContext.getBean("batchQueryThreadPool", EnhancedThreadPoolExecutor.class)));
}
}
}
return (flag, scene, context) -> strategyHandles.get(scene + flag).apply(context);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public interface CommonStrategy<T, R> {
/**
* 执行
*
* @param flag
* 关键字
* @param scene
* 场景
* @param context
* 上下文
* @return {@link R}
*/
R run(String flag, String scene, T context);
}
public interface CommonFutureStrategy<T, R> {
/**
* 异步执行
*
* @param flag
* 关键字
* @param scene
* 场景
* @param context
* 上下文
* @return {@link R}
*/
CompletableFuture<R> runAsync(String flag, String scene, T context);
}
}
4、定义具体策略
@StrategyFlag(value = "2", scene = "threshold", desc = "三五证状态")
@Component
public class CertificatesHandle {
@Resource
private LionConfig lionConfig;
@Resource
private UserCenterRpc userCenterRpc;
@StrategyHandler
public ThresholdInfo run(ThresholdContext context) {
if (Objects.isNull(context) || Objects.isNull(context.getMemberAccountGrowth())
|| Objects.isNull(context.getThresholdInfoConfig())) {
return null;
}
final ThresholdInfo thresholdInfo = new ThresholdInfo();
return thresholdInfo;
}
}
5、实际调用
thresholdInfoConfigs.forEach(x -> {
thresholdInfoFuture.add(commonFutureStrategy.runAsync(x.getTaskType() + "", "threshold",
new ThresholdContext().setThresholdInfoConfig(x).setMemberAccountGrowth(growth)));
});
// 阻塞等待所有返回
CompletableFuture.allOf(thresholdInfoFuture.toArray(new CompletableFuture[] {})).get(2000,
TimeUnit.MILLISECONDS);
for (CompletableFuture<ThresholdInfo> completableFuture : thresholdInfoFuture) {
ThresholdInfo batchQueryResult = completableFuture.get();
if (Objects.nonNull(batchQueryResult)) {
thresholdInfos.add(batchQueryResult);
}
}