设计模式之责任链模式(结合servlet源码和dubbo 源码讲解)

设计模式之责任链模式(结合servlet源码和dubbo 源码讲解),第1张

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 LinkedList<>();

    public FilterChannel addFilter(FilterService filterService) {
        filterServiceList.add(filterService);
        return this;
    }

    public Object doFilter(FilterContext context) {
        if (index < filterServiceList.size()) {
            return filterServiceList.get(index++).filter(context, this);
        }
        return null;
    }

    public static void main(String[] args) {

        new FilterChannel().addFilter(new FilterServiceImpl1())
                .addFilter(new FilterServiceImpl2()).doFilter(new FilterContext());
    }
}

interface FilterService {
    Object filter(FilterContext context, FilterChannel channel);
}

class FilterContext {

}

class FilterServiceImpl1 implements FilterService {

    @Override
    public Object filter(FilterContext context, FilterChannel channel) {
        System.out.println("i am filter 1");
        return channel.doFilter(context);
    }
}

class FilterServiceImpl2 implements FilterService {

    @Override
    public Object filter(FilterContext context, FilterChannel channel) {
        System.out.println("i am filter 2");
        return channel.doFilter(context);
    }
}
package com.designmode.responsiabilitychannel;

import java.util.Arrays;
import java.util.List;

public class ResponsibilityChannelImpl{
    public static void main(String[] args){
        Invoker next = (context)->{return "end filter channel";};
        List<Filter> filterList = Arrays.asList(new TestFilter1(),new TestFilter2());

        for(int i=filterList.size()-1;i>=0;i--){
            int finalI = i;
            Invoker finalInvokerNext = next;
            next = (context)->
               filterList.get(finalI).filter(context,finalInvokerNext);
        }
        System.out.println(next.invoke(new InvocationContext()));
    }
}


interface Invoker {
    Object  invoke(InvocationContext invocationContext);
}


class InvocationContext{

}

interface Filter{
    Object filter(InvocationContext invocationContext,Invoker invoker);
}

class TestFilter1 implements Filter{

    @Override
    public Object filter(InvocationContext invocationContext, Invoker invoker) {
        System.out.println("i am testFilter 1");
        return invoker.invoke(invocationContext);
    }
}

class TestFilter2 implements Filter{

    @Override
    public Object filter(InvocationContext invocationContext, Invoker invoker) {
        System.out.println("i am testFilter 2");
        return invoker.invoke(invocationContext);
    }
}




欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/922281.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-16
下一篇 2022-05-16

发表评论

登录后才能评论

评论列表(0条)

保存