引言 在软件开发过程中,经常会遇到需要对请求进行一系列处理的情况。例如,在Web应用中,用户的请求可能需要经过身份验证、权限检查、数据校验等步骤。为了使代码结构清晰、降低耦合度、提高可扩展性,可以使用责任链模式 来解决此类问题。
责任链模式定义 责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它通过将多个处理者(Handler)按照顺序组成一条链,当有请求发生时,沿着这条链依次传递,直到有处理者处理它或处理链结束。该模式使请求的发送者和接收者解耦,客户端无需知道是哪一个处理者最终处理了请求,增强了系统的灵活性。
比如在一个采购系统中,用户需要进行采购下单,对采购的商品会进行很多校验,比如用户是否符合采购用户标准,用户采购的订单库存是否充足,用户需要送达的地址是否可以送到等等一系列校验。按照需求快速开发我们就会在一个校验的方法里面,判断上述一系列条件是否满足,满足才可以生成订单。后面系统进行二次迭代,vip 用户不需要下单,也不需要进行地址校验,这时候可能会加入一个if vip user
的判断 然后再决定是否执行校验,这样简单一次代码结果还好,但是随着系统的不断迭代,特定场景的订单越来越多,判断条件也越加越多,于是乎代码结果就变得难以阅读和维护。
参考Servlet 的Filter + FilterChain, 可以构建一个订单创建的职责链路,根据业务类型来指定对应的职责链路。
Servlet 里面的Filter 和FilterChain 使用的就是责任链模式。每一个职责可以组装,比如filterchain 也有不同的实现
Filter 接口 -> 实现处理过程
FilterChain 接口 -> 定义调用链路 责任链模式建议你将这些处理者连成一条链。 链上的每个处理者都有一个成员变量来保存对于下一处理者的引用。 除了处理请求外, 处理者还负责沿着链传递请求。 请求会在链上移动, 直至所有处理者都有机会对其进行处理。
写点代码 以订单创建为例子,会对订单的信息校验,然后再进行创建,如果不满足条件则退出,每种特定的行为的处理都会影响订单创建的结果。
快速开发if-else 一把锁
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 public class OrderService { void creteOrder () { OrderBO orderBO = new OrderBO (); if (checkState(orderBO)) { } if (checkAddress(orderBO)) { } if (checkXXX(orderBO)) { } } private boolean checkXXX (OrderBO orderBO) { return false ; } private boolean checkAddress (OrderBO orderBO) { return false ; } private boolean checkState (OrderBO orderBO) { return false ; } }
使用责任链模式拆分业务逻辑
OrderBO ,订单业务对象
OrderFilter ,订单处理过滤器接口
OrderAddressFilter 实现 OrderFilter
OrderStateFilter 实现OrderFilter
OrderFilterChain构建订单过滤链路,
包含doFilter 和addFilter 方法,维护一个过滤器链表
OrderFilterTest指定需要的链路,然后执行过滤。具体代码如下所示
1 2 3 4 5 public interface OrderFilter { void doFilter (OrderBO order, OrderFilterChain chain) ; }
1 2 3 4 5 6 7 8 9 10 11 12 @Slf4j @Component(OrderFilterConstant.ADDRESS) public class OrderAddressFilter implements OrderFilter { @Override public void doFilter (OrderBO order, OrderFilterChain orderFilterChain) { log.info("执行地址过滤" ); orderFilterChain.doFilter(order); } }
1 2 3 4 5 6 7 8 9 10 //订单状态校验过滤器 @Component(OrderFilterConstant.State) @Slf4j public class OrderStateFilter implements OrderFilter { @Override public void doFilter(OrderBO order, OrderFilterChain orderFilterChain) { log.info("执行订单状态过滤"); orderFilterChain.doFilter(order); } }
订单创建责任链
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 @Slf4j @Component public class OrderFilterChain { private int size; private int position = 0 ; private OrderFilter[] orderFilters = new OrderFilter [10 ]; public void doFilter (final OrderBO order) { if (this .position < this .size) { OrderFilter orderFilter = orderFilters[position++]; orderFilter.doFilter(order, this ); } } public void addFilter (OrderFilter orderFilter) { if (orderFilters.length == size) { OrderFilter[] newOrderFilters = new OrderFilter [size + 10 ]; System.arraycopy(orderFilters, 0 , newOrderFilters, 0 , size); orderFilters = newOrderFilters; } orderFilters[size++] = orderFilter; } }
客户端测试代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @SpringBootTest public class OrderFilterTest { @Autowired private OrderFilterChain orderFilterChain; @Autowired private Map<String, OrderFilter> orderFilterMap; @Autowired private List<OrderFilter> orderFilters; @Test public void test () { for (OrderFilter orderFilter : orderFilters) { orderFilterChain.addFilter(orderFilter); } orderFilterChain.doFilter(null ); } }
如果想要指定新的责任链,比如A业务不需要进行某个校验,那么在client 调用的时候,就不要添加到filterChain 即可
总结 在上面的案例中,我们把订单创建的每一个职责抽取成了单独的Filter ,每一个filter 可以通过FilterChain 进行链式调用。如果后续有新的责任链路的时候,可以在调用方指定校验链路的顺序和类型,实现对应的业务逻辑处理。
在使用责任链模式之后,后续迭代时既不需要修改原有的代码,也可以重新编排新的FilterChain。