策略模式

解析代码:public class CalculateServiceImpl {

@Resource private List<CalculateHandler> handlers;

private Map<String, CalculateHandler> handlersMap;

@PostConstruct public void init() {

handlersMap = handlers.stream().collect(Collectors.toMap(CalculateHandler::getKey, Function.identity(), (v1, v2) -> v1));

}

 非拉姆达写法:

handlersMap = handlers.stream()
.collect(Collectors.toMap(
new Function<CalculateHandler, String>() {
@Override
public String apply(CalculateHandler handler) {
return handler.getKey();
}
},
new Function<CalculateHandler, CalculateHandler>() {
@Override
public CalculateHandler apply(CalculateHandler handler) {
return handler; // Function.identity()
}
},
new BinaryOperator<CalculateHandler>() {
@Override
public CalculateHandler apply(CalculateHandler v1, CalculateHandler v2) {
return v1; // 冲突时保留第一个
}
}
));

 

这段代码是一个典型的 Spring 场景下的策略模式初始化逻辑,用于将一组 CalculateHandler 实现类注册到一个 Map 中,以便后续根据 key 快速查找对应的处理器。

✅ 逐行解析

java
复制
public class CalculateServiceImpl {
 
  • 这是一个服务实现类,可能是某个计算服务的具体实现。

java
复制
@Resource
private List<CalculateHandler> handlers;
 
  • 使用 @Resource(Spring 支持的注解)注入 所有实现了 CalculateHandler 接口的 Bean。
  • Spring 会自动收集容器中所有 CalculateHandler 类型的 Bean,组成一个 List 注入进来。
  • 这是 策略模式 的典型用法:每个 CalculateHandler 实现类代表一种计算策略。

java
复制
private Map<String, CalculateHandler> handlersMap;
 
  • 用于存储 key -> CalculateHandler 的映射关系。
  • 目的是后续可以通过 key 快速获取对应的处理器,避免遍历 List

java
复制
@PostConstruct
public void init() {
 
  • @PostConstruct 表示 在依赖注入完成后自动执行 的方法。
  • 用于初始化 handlersMap

java
复制
handlersMap = handlers.stream()
    .collect(Collectors.toMap(
        CalculateHandler::getKey,        // key 提取器
        Function.identity(),             // value 就是 handler 本身
        (v1, v2) -> v1                   // 如果 key 重复,保留第一个
    ));
 
  • List<CalculateHandler> 转换为 Map<String, CalculateHandler>
  • CalculateHandler::getKey:每个 handler 提供一个 getKey() 方法,返回其唯一标识。
  • Function.identity():value 就是 handler 本身。
  • (v1, v2) -> v1:如果两个 handler 的 key 相同,保留第一个,忽略后面的。

✅ 总结一句话

这段代码的作用是:在 Spring 启动时,自动收集所有 CalculateHandler 实现类,并以 getKey() 的返回值为键,构建一个映射表,方便后续根据 key 快速获取对应的处理器。

✅ 举个例子

假设你有:
java
复制
public interface CalculateHandler {
    String getKey();
    BigDecimal calculate(BigDecimal a, BigDecimal b);
}

@Component
class AddHandler implements CalculateHandler {
    public String getKey() { return "ADD"; }
    public BigDecimal calculate(BigDecimal a, BigDecimal b) { return a.add(b); }
}

@Component
class SubtractHandler implements CalculateHandler {
    public String getKey() { return "SUB"; }
    public BigDecimal calculate(BigDecimal a, BigDecimal b) { return a.subtract(b); }
}
 
那么 init() 执行后:
java
复制
handlersMap = {
    "ADD"  -> AddHandler,
    "SUB"  -> SubtractHandler
}
 

✅ 后续使用示例

java
复制
public BigDecimal execute(String key, BigDecimal a, BigDecimal b) {
    CalculateHandler handler = handlersMap.get(key);
    if (handler == null) throw new IllegalArgumentException("Unsupported key: " + key);
    return handler.calculate(a, b);
}
 

✅ 小结

表格
复制
元素作用
@Resource List<CalculateHandler> 收集所有策略实现
@PostConstruct init() 初始化策略映射表
Collectors.toMap(...) 构建 key -> handler 的映射
getKey() 每个策略的唯一标识

如果你有 CalculateHandler 的源码,我可以帮你看看它的 getKey() 是怎么实现的。
posted @ 2025-10-28 11:41  人在代码在  阅读(1)  评论(0)    收藏  举报