责任链设计模式的思想简单的来说,就是把一个个处理逻辑以链式的方式连接起来,整条链的任意一个节点都可选择中断或继续传递。直到整个链路处理完。像很多框架和中间件的都有用到责任链设计模式。如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的位置。
dubbo filter的责任链实现更像是基于链表的实现,每一个filter会被包装成一个Invoker对象,前个filter invoker对象会保存下一个filter Invoker对象的引用,形成一个链式结构。
如下,通过spi获取所有的Filter实现,从最后的filter节点开始构建Invoker对象,通过匿名内部类巧妙的将 filter Invoke对象串起来。
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);
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)