1.什么是责任链设计模式
责任链设计模式的思想简单的来说,就是把一个个处理逻辑以链式的方式连接起来,整条链的任意一个节点都可选择中断或继续传递。直到整个链路处理完。像很多框架和中间件的都有用到责任链设计模式。如servlet的filter channel,dubbo的filter执行等等。
2.责任链设计模式的好处
责任链设计模式可以使代码解耦开来,举个例子现在有个下完单送会员的需求,但是下单要满足各种条件才能送会员,而且后续需求还可能发生变化,如果按照我们常规的写法要写大量的if判断,代码都糅合在一起,不利于拓展和维护。而利用责任链设计模式则可以把一个一个if判断拆分成链中的一个点,可以随时中断或继续向下传播。下面我就以目前比较常见的2种责任链设计模式的实现来给大家讲解下。
3.servlet API FilterChannel 的责任链的具体实现
servlet api中的Filter 接口相比大家都不陌生,filter 执行在servlet之前。
主要可执行一些校验,鉴权,或者对request,response做一些增强的处理逻辑。
public interface Filter {
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException;
}
doFilter方法有一个FilerChannel对象,如果想要FilterChannel对象继续往下传播则需要调用chain的doFilter方法。
FilterChannel的核心实现:FilterChannel实例内部有一个Filter 的List集合,还有一个pos变量用来记录当前执行到哪一个filter了。其本质是基于数组实现的,用一个变量记录当前执行Filter的位置。
4.dubbo 的 filter拦截链的实现
dubbo filter的责任链实现更像是基于链表的实现,每一个filter会被包装成一个Invoker对象,前个filter invoker对象会保存下一个filter Invoker对象的引用,形成一个链式结构。
如下,通过spi获取所有的Filter实现,从最后的filter节点开始构建Invoker对象,通过匿名内部类巧妙的将 filter Invoke对象串起来。
5. 2种责任链的简单实现
package com.designmode.responsiabilitychannel;
import java.util.LinkedList;
import java.util.List;
public class FilterChannel {
private int index;
private List<FilterService> filterServiceList = new Lin