责任链模式详解(下)

简介: 责任链模式详解

定义调用入口


OrderHandlerChain 是外部调用的入口,其实它主要的作用就是获取 AbstractOrderHandler 并且排序(即串联/编排 Handler ) 然后进行执行。这里我充分使用了 Spring 的 Bean 排序功能,通过在 Handler 上面定义 @Order 注解并且传入顺序值,我们在 @Autowired 获取 List 的时候,Spring 会给我自动注入排好序的 handlerList 。


@Slf4j
@Component
public class OrderHandlerChain {
    @Autowired
    private List<AbstractOrderHandler> chain;
    @Autowired
    private ApplicationContext applicationContext;
    public void handle(OrderHandleContext context, Object... objects) {
        if (context.getPos() < chain.size()) {
            AbstractOrderHandler handler = chain.get(context.getPos());
            // 移动位于处理器链中的位置
            context.setPos(context.getPos() + 1);
            handler.doHandle(context, this, objects);
        }
    }
}


业务拓展


如果我的订单逻辑发生变化,需要支持汽车订单的创建和兼容。我们可以增加 Car 处理的 handler 通过指定不同 OrderTypeEnum 进行处理,如果你不想创建更多的 handler 类文件也可以通过 @Bean 来进行实现。 这里其实也是一种妥协的方式,其实和直接实现 AbstractOrderHandler 并没有什么区别,都会生成 .class 文件,只是说在开发侧来看少了一个 Java 文件而已,也会占 JVM 的 Metaspace 空间。 如下所示:


@Configuration
public class CarOrderHandlers {
    /**
     * 汽车订单创建
     *
     * @return
     */
    @Bean(name = "createOrderByCar")
    public AbstractOrderHandler createOrderByCar() {
        return new CreateOrderHandler() {
            @Override
            protected OrderTypeEnum getTypeEnum() {
                return OrderTypeEnum.Car;
            }
            @Autowired
            private ApplicationContext applicationContext;
            @Override
            protected void doHandle(OrderHandleContext context, Object... args) {
                System.out.println("car order create ....");
            }
        };
    }
}


测试代码


测试代码如下,我们只需要传入一个 Context 对象然后调用 chain.handle 方法即可。


@Slf4j
@SpringBootTest(classes = App.class)
public class OrderHandlerChainTest {
    @Resource
    private OrderHandlerChain chain;
    @Test
    public void testOrderChain() {
        OrderHandleContext context = new OrderHandleContext();
        context.setTypeEnum(OrderTypeEnum.Car);
        chain.handle(context, null);
    }
}


总结


本文主要是利用了 Spring 进行排序, Bean 定义等特征,实现责任链。感觉改造过后,有一点策略 + 模板 的感觉。策略模式主要是运用: 多方案切换的场景对业务进行垂直路由分别处理。责任链模式主要运用:责任传递的场景对业务进行水平分段处理粒度可以说更加细一些。


其实我们 JDK8 还提供了 @FunctionalInterface 函数接口,我们也可以将 AbstractOrderHandler 修改为 interface 接口,这样我们就可以通过 _lambda 表达式的方式注册 _Handler 其实本质都是一样的。


参考文章




相关文章
|
4月前
|
设计模式 缓存 监控
Java设计模式-责任链模式(17)
Java设计模式-责任链模式(17)
|
5月前
|
设计模式
|
7月前
|
设计模式 JavaScript 前端开发
如何优雅的使用责任链模式?
【6月更文挑战第7天】如何优雅的使用责任链模式?
|
7月前
|
设计模式 Java
Java设计模式之责任链模式详解
Java设计模式之责任链模式详解
|
设计模式 Java
设计模式~~~责任链模式(职责链模式)
设计模式~~~责任链模式(职责链模式)
77 0
|
JavaScript 测试技术
关于责任链模式我所知道的
关于责任链模式我所知道的
93 0
|
设计模式 Java
Java设计模式—责任链模式
Java设计模式—责任链模式
142 0
Java设计模式—责任链模式
责任链模式简单介绍
责任链模式简单介绍
145 0
|
Java Nacos Sentinel
责任链模式详解(上)
责任链模式详解
244 0
责任链模式详解(上)
|
设计模式 XML 数据格式