java责任链模式完整版

393 阅读3分钟

什么是责任链?

一个很简单的例子就是servlet中比较出名的http请求过滤器,每一个filter负责去过滤掉一部分东西

举个例子:就是类似这个掘金的发博客系统,每一个用户发博客,都需要去检测里面的内容是否包括敏感词,或者可疑

代码,可以自己手动去过滤但是太麻烦了,这就需要过滤器来帮助我们了,但是可能有很多个过滤器,那么不就需要一

个List 来存储filter,如果把一个一个的filter加入到里面去,但是这样没用设计思想,且不方便,

进而我们封装成filterchain 过滤链,只有把过滤器加到里面去,自动帮我们过滤

设计模式中最重要----的原则就是分装变化,把变化的代码封装起来。

这里我们来模仿做一个责任链模式的filter,

要求1:过滤request和response请求

要求2:先进后出,先走第一个request然后第二个request 再第二个response --最后第一个responss;

servlet就是这么设计的

不说了上代码

第一步 封装request类和response类

class Req{
	public String request;
}

class Response{
	public String response;
}

为了简单就这么构建类

构建filter接口

interface Filter{
	void doFilter(Req req,Response response,FilterChain filterChain);
}

前两个参数是因为我们要对这个处理,比较好理解,那第三个参数是为了什么呢?

为了获取到这个联中具体的位置,你想啊 这个如果你不要,那直接处理完第一个的request后走第一个response,不就结束了,第二个都没用机会,所以啊,要自己来控制这个链,其实就是递归的手法。

class HtmlFilter implements  Filter{

	@Override
	public void doFilter(Req req,Response response,FilterChain filterChain) {
		System.out.println("第一次H  request");
		filterChain.doFilter(req,response,filterChain);
		System.out.println("第一次H  response");

	}
}
class SensitiveFilter implements Filter{

	@Override
	public void doFilter(Req req,Response response,FilterChain filterChain) {
		System.out.println("第一次S  request");
		filterChain.doFilter(req,response,filterChain);
		System.out.println("第一次S  response");


	}
}

这里我写了两个类,是继承与上面的接口,第一行模仿处理request 第三行是模仿处理response

中间的有疑惑吗? 就是递归到下一个filter里面去 里面的处理完,再出来处理自己的response刚刚好就完成了第二个要求 嘻嘻

filterchain里面的dofilter就是为了处理获取到当前的filter并进入到下一个

class FilterChain implements Filter{
	private List<Filter>filterList=new ArrayList<>();
	int index=0;

	public FilterChain add(Filter filter){
		filterList.add(filter);
		return this;
	}

	@Override
	public void  doFilter(Req req,Response response,FilterChain filterChain){
		int size = filterList.size();
		if (index==size){

		}else {
			Filter filter = filterList.get(index);
			//进去之前把这个改了不然永远都获得的是这个index,为了运行下一个filter
			index++;
			filter.doFilter(req,response,filterChain);

		}

	}

我们通过一个index来控制每一个filter 那为什么要让FilterChain实现filter,是为了方便两个链相加, 因为add方法是可以加入filter的

测试


		Req req = new Req();
		req.request="req";
		Response response = new Response();
		response.response="response";
		FilterChain filterChain = new FilterChain();
		filterChain.add(new HtmlFilter());
		filterChain.add(new SensitiveFilter());
		filterChain.doFilter(req,response,filterChain);

image.png