责任链模式组件封装

91 阅读1分钟

1.创建自动配置类

public class DesignPatternAutoConfiguration {
    @Autowired
    private ApplicationContext context;

    /**
     * 责任链上下文
     */
    @Bean
    public AbstractChainContext abstractChainContext() {
        return new AbstractChainContext(context);
    }
}

2.spring.facotries添加自动配置类

3.抽象责任链上下文

public final class AbstractChainContext<T> implements CommandLineRunner {
    private ApplicationContext context;
    private final Map<String, List<AbstractChainHandler>> abstractChainHandlerContainer = Maps.newHashMap();

    public AbstractChainContext(ApplicationContext context) {
        this.context=context;
    }

    /**
     * 责任链组件执行
     *
     * @param mark         责任链组件标识
     * @param requestParam 请求参数
     */
    public void handler(String mark, T requestParam) {
        List<AbstractChainHandler> abstractChainHandlers = abstractChainHandlerContainer.get(mark);
        if (CollectionUtils.isEmpty(abstractChainHandlers)) {
            throw new RuntimeException(String.format("[%s] Chain of Responsibility ID is undefined.", mark));
        }
        abstractChainHandlers.forEach(each -> each.handler(requestParam));
    }

    @Override
    public void run(String... args) throws Exception {
        Map<String, AbstractChainHandler> chainFilterMap = context
                .getBeansOfType(AbstractChainHandler.class);
        chainFilterMap.forEach((beanName, bean) -> {
            List<AbstractChainHandler> abstractChainHandlers = abstractChainHandlerContainer.get(bean.mark());
            if (CollectionUtils.isEmpty(abstractChainHandlers)) {
                abstractChainHandlers = new ArrayList();
            }
            abstractChainHandlers.add(bean);
            List<AbstractChainHandler> actualAbstractChainHandlers = abstractChainHandlers.stream()
                    .sorted(Comparator.comparing(Ordered::getOrder))
                    .collect(Collectors.toList());
            abstractChainHandlerContainer.put(bean.mark(), actualAbstractChainHandlers);
        });
    }
}

4.抽象责任链处理接口

public interface AbstractChainHandler<T> extends Ordered {

    /**
     * 执行责任链逻辑
     *
     * @param requestParam 责任链执行入参
     */
    void handler(T requestParam);

    /**
     * @return 责任链组件标识
     */
    String mark();
}

5.使用

创建责任链过滤器,继承抽象责任链处理接口

public interface OrderCreateChainFilter<T extends OrderCreateCommand> extends AbstractChainHandler<OrderCreateCommand> {

    @Override
    default String mark() {
        return OrderChainMarkEnum.ORDER_CREATE_FILTER.name();
    }
}

创建责任链处理器,实现责任链过滤器,并设定order

@Component
public final class OrderCreateParamNotNullChainHandler implements OrderCreateChainFilter<OrderCreateCommand> {

    @Override
    public void handler(OrderCreateCommand requestParam) {
        if (Objects.isNull(requestParam.getCustomerUserId())) {
            throw new BizException(OrderCreateErrorCodeEnum.CUSTOMER_USER_ID_NOTNULL);
        } else if (Objects.isNull(requestParam.getTotalAmount())) {
            throw new BizException(OrderCreateErrorCodeEnum.TOTAL_AMOUNT_NOTNULL);
        } else if (Objects.isNull(requestParam.getPayAmount())) {
            throw new BizException(OrderCreateErrorCodeEnum.PAY_AMOUNT_NOTNULL);
        } else if (Objects.isNull(requestParam.getFreightAmount())) {
            throw new BizException(OrderCreateErrorCodeEnum.FREIGHT_AMOUNT_NOTNULL);
        } else if (Objects.isNull(requestParam.getSource())) {
            throw new BizException(OrderCreateErrorCodeEnum.SOURCE_NOTNULL);
        }
        // xxx 这里应该把所有订单入参校验必填,因为重复工作量所以暂时验证上述这些
    }

    @Override
    public int getOrder() {
        return 0;
    }
}

通过注入抽象责任链上下文即可使用

@Resource
private AbstractChainContext<OrderCreateCommand> abstractChainContext;


@PostMapping("/create")
public void createOrder(@RequestBody OrderCreateCommand requestParam) {
    try{
        // 责任链模式: 执行订单创建参数验证
        abstractChainContext.handler(OrderChainMarkEnum.ORDER_CREATE_FILTER.name(), requestParam);
        //订单其它逻辑
    }catch (BizException e){
        System.out.println(e.getErrMsg());
    }
}