设计模式-责任树模型

责任树模型由责任链+策略模式构成

责任树模型通常用于解决多个层级关系复杂业务场景,业务执行时,可以像树一样,路由到适配的节点进行处理,也可以使用所有的节点处理同一个事件。

其代码结构如下:

接口



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;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值