责任链模式的两种实现

实现一:servlet 经典模式 责任链模式的两种实现
文章图片

该模式特点:多线程环境环境下,需要每一个客户端请求,new 一个ConcreteFilterChain对象。如果对象太大,增加cpu和gc的负担。
代码demo

import java.io.IOException; public interface Filter { public void doFilter(Context ctx, FilterChain chain) throws IOException; }

import java.io.IOException; public interface FilterChain { void doFilter(Context ctx) throws IOException; }

import java.io.IOException; public class PrintOne implements Filter { @Override public void doFilter(Context ctx, FilterChain chain) throws IOException { System.out.println(Thread.currentThread().getId()+ " 1"); chain.doFilter(ctx); }}import java.io.IOException; public class PrintTwo implements Filter { @Override public void doFilter(Context ctx, FilterChain chain) throws IOException {System.out.println(Thread.currentThread().getId()+" 2"); chain.doFilter(ctx); } }import java.io.IOException; public class PrintThree implements Filter { @Override public void doFilter(Context ctx, FilterChain chain) throws IOException {System.out.println(Thread.currentThread().getId()+" 3"); chain.doFilter(ctx); } }

import java.io.IOException; import java.util.List; public class DefaultFilterChain implements FilterChain {public DefaultFilterChain(List list) { this.list = list; }List list; int pos = 0; @Override public void doFilter(Context ctx) throws IOException { if(pos < list.size()){ Filter filter = list.get(pos); pos++; filter.doFilter(ctx,this); } } }

测试程序
import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class TestMain { static ExecutorService executorService = Executors.newFixedThreadPool(5); public static void main(String args[]){ List list = new ArrayList(); list.add(new PrintOne()); list.add(new PrintTwo()); list.add(new PrintThree()); FilterChain filterChain = new DefaultFilterChain(list); for(int i=0; i<2; i++) { executorService.submit(new Event(filterChain)); } }public static class Event implements Runnable{ public Event(FilterChain filterChain) { this.filterChain = filterChain; }FilterChain filterChain; @Override public void run() { Context ctx = new Context(); try {filterChain.doFilter(ctx); } catch (IOException e) { e.printStackTrace(); } } } }

注意:该测试程序是有bug的,多线程共享filterChain会导致filter的游标定位错误。要解决这个问题,要么每个请求new一个DefaultFilterChain对象。
实现二 参考netty pipeline的实现
责任链模式的两种实现
文章图片

该实现的优点:多线程环境下,不需要每一个客户的请求都new一个DefaultFilterChain.该算法的巧妙之处在于:将handler跟filterchain 组成成一个节点。 通过handler驱动节点的扭转
上代码
public class Context { }public interface Handler { void handle(Context ctx,FilterChain filterChain); }public class PrintOne implements Handler { @Override public void handle(Context ctx, FilterChain filterChain) { System.out.println(Thread.currentThread().getId()+" 1"); filterChain.fireNext(ctx); } }public class PrintTwo implements Handler{ @Override public void handle(Context ctx, FilterChain filterChain) { System.out.println(Thread.currentThread().getId()+" 2"); filterChain.fireNext(ctx); } }public class PrintThree implements Handler { @Override public void handle(Context ctx, FilterChain filterChain) { System.out.println(Thread.currentThread().getId()+" 3"); filterChain.fireNext(ctx); } }

FilterChain和DefaultFilterChain
public interface FilterChain { void handler(Context ctx); void fireNext(Context ctx); }public class DefaultFilterChain implements FilterChain { private FilterChain next; private Handler handler; public DefaultFilterChain(FilterChain next, Handler handler) { this.next = next; this.handler = handler; }@Override public void handler(Context ctx) { handler.handle(ctx,this); }public void fireNext(Context ctx){ FilterChain next_ = this.next; if(next_ != null){ next_ .handler(ctx); }} }

测试代码
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class FilterChainTest { static ExecutorService executorService = Executors.newFixedThreadPool(3); public static void main(String args[]){Handler h1 = new PrintOne(); Handler h2 = new PrintTwo(); Handler h3 = new PrintThree(); FilterChain filterChain3 = new DefaultFilterChain(null,h3); FilterChain filterChain2 = new DefaultFilterChain(filterChain3,h2); FilterChain filterChain1 = new DefaultFilterChain(filterChain2,h1); Context ctx = new Context(); for(int i=0; i<3; i++){ executorService.execute(new RunPrintEcho(filterChain1,ctx)); }}public static class RunPrintEcho implements Runnable{ FilterChain filterChain; Context ctx; public RunPrintEcho(FilterChain filterChain, Context ctx) { this.filterChain = filterChain; this.ctx = ctx; }@Override public void run() { filterChain.handler(this.ctx); } } }

【责任链模式的两种实现】大功告成!

    推荐阅读