责任树模型由责任链+策略模式构成
责任树模型通常用于解决多个层级关系复杂业务场景,业务执行时,可以像树一样,路由到适配的节点进行处理,也可以使用所有的节点处理同一个事件。
其代码结构如下:
接口
public interface StrategyHandler<T, R> {
@SuppressWarnings("rawtypes")
StrategyHandler DEFAULT = t -> null;
/**
* apply strategy
*
* @param param
* @return
*/
R apply(T param);
}
抽象类策略路由
import lombok.Getter;
import lombok.Setter;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.Objects;
/**
* 通用的“策略树“框架,通过树形结构实现分发与委托,每层通过指定的参数进行向下分发委托,直到达到最终的执行者。
* 该框架包含两个类:{@code StrategyHandler} 和 {@code AbstractStrategyRouter}
* 其中:通过实现 {@code AbstractStrategyRouter} 抽象类完成对策略的分发,
* 实现 {@code StrategyHandler} 接口来对策略进行实现。
* 像是第二层 A、B 这样的节点,既是 Root 节点的策略实现者也是策略A1、A2、B1、B2 的分发者,这样的节点只需要
* 同时继承 {@code StrategyHandler} 和实现 {@code AbstractStrategyRouter} 接口就可以了。
*
* <pre>
* +---------+
* | Root | ----------- 第 1 层策略入口
* +---------+
* / \ ------------- 根据入参 P1 进行策略分发
* / \
* +------+ +------+
* | A | | B | ------- 第 2 层不同策略的实现
* +------+ +------+
* / \ / \ --------- 根据入参 P2 进行策略分发
* / \ / \
* +---+ +---+ +---+ +---+
* |A1 | |A2 | |B1 | |B2 | ----- 第 3 层不同策略的实现
* +---+ +---+ +---+ +---+
* </pre>
*
* @see StrategyHandler
*/
@Component
public abstract class AbstractStrategyRouter<T, R> {
/**
* 策略映射器,根据指定的入参路由到对应的策略处理者。
*
* @param <T> 策略的入参类型
* @param <R> 策略的返回值类型
*/
public interface StrategyMapper<T, R> {
/**
* 根据入参获取到对应的策略处理者。可通过 if-else 实现,也可通过 Map 实现。
*
* @param param 入参
* @return 策略处理者
*/
StrategyHandler<T, R> get(T param);
}
private StrategyMapper<T, R> strategyMapper;
/**
* 类初始化时注册分发策略 Mapper
*/
@PostConstruct
private void abstractInit() {
strategyMapper = registerStrategyMapper();
// Objects.requireNonNull(strategyMapper, "strategyMapper cannot be null");
}
@Getter
@Setter
@SuppressWarnings("unchecked")
private StrategyHandler<T, R> defaultStrategyHandler = StrategyHandler.DEFAULT;
/**
* 执行策略,框架会自动根据策略分发至下游的 Handler 进行处理
*
* @param param 入参
* @return 下游执行者给出的返回值
*/
public R applyStrategy(T param) {
final StrategyHandler<T, R> strategyHandler = strategyMapper.get(param);
if (strategyHandler != null) {
return strategyHandler.apply(param);
}
return defaultStrategyHandler.apply(param);
}
/**
* 抽象方法,需要子类实现策略的分发逻辑
*
* @return 分发逻辑 Mapper 对象
*/
protected abstract StrategyMapper<T, R> registerStrategyMapper();
}
应用
@Slf4j
@Component
public class DoctorQualityRootService extends AbstractStrategyRouter<QualityDoctorCalculateParam, QualityDoctorScoreDTO> implements StrategyHandler<QualityDoctorCalculateParam, QualityDoctorScoreDTO> {
@Resource
private OperationScoreLeafService operationScoreLeafService;
@Resource
private QualityScoreLeafService qualityScoreLeafService;
/**
* 定义用来存储执行策略的map集合
*/
@Getter
@Setter
private Map<String, StrategyHandler> strategyMap = new ConcurrentHashMap<>();
/**
* 创建某个节点下的策略或节点
*
* @return
*/
@Override
public StrategyMapper<QualityDoctorCalculateParam, QualityDoctorScoreDTO> registerStrategyMapper() {
strategyMap.put(HandlerRouterEnum.OPERATION_SCORE.getHandlerName(), Optional.ofNullable(operationScoreLeafService).orElse(new OperationScoreLeafService()));
strategyMap.put(HandlerRouterEnum.QUALITY_SCORE.getHandlerName(), Optional.ofNullable(qualityScoreLeafService).orElse(new QualityScoreLeafService()));
return new RootStrategyMapperImpl(strategyMap);
}
public StrategyHandler<QualityDoctorCalculateParam, QualityDoctorScoreDTO> getHandler(QualityDoctorCalculateParam param) {
return strategyMap.get(param);
}
/**
* 实现父类定义的接口,用于实现自己的获取不同的策略
*/
public class RootStrategyMapperImpl implements StrategyMapper<QualityDoctorCalculateParam, QualityDoctorScoreDTO> {
private Map<String, StrategyHandler> strategyMap1;
RootStrategyMapperImpl(Map map) {
strategyMap1 = map;
}
@Override
public StrategyHandler<QualityDoctorCalculateParam, QualityDoctorScoreDTO> get(QualityDoctorCalculateParam param) {
return strategyMap.get(param.getHandlerLevelTwo().getHandlerName());
}
}
@Override
public QualityDoctorScoreDTO apply(QualityDoctorCalculateParam param) {
return scoreDTO;
}
}