【设计模式】责任链4-链接链

紧接着上一个问题来:

为了不要跟原来的代码冲突,又新建了一个工程,将所有代码放在一起。
代码清单:(为了测试简洁,去掉了FaceFilter.java)
Filter.java
FilterChain.java
HTMLFilter.java
Main.java
MsgProcessor.java
Request.java
Response.java
SesitiveFilter.java

因为新加入了Response和Request类,我们要改写几个类:
改写Filter.java:

package cn.edu.hpu.filter.web;

public interface Filter {

	void doFilter(Request request,Response response);
}

参数该成request和response

改写FilterChian:

package cn.edu.hpu.filter.web;

import java.util.List;
import java.util.ArrayList;

public class FilterChain implements Filter{
	List<Filter> filters=new ArrayList<Filter>();

	//返回值是FilterChain只为了在Main中满足链条式的编程
	public FilterChain addFilter(Filter f) {
		this.filters.add(f);
		return this;
	}

	@Override
	public void doFilter(Request request,Response response) {
		for(Filter f:filters){
			f.doFilter(request,response);
		}
	}
}

具体的各种Filter我们就应该这么做了(先处理request请求):
HTMLFilter:

package cn.edu.hpu.filter.web;

public class SesitiveFilter implements Filter {
	@Override
	public void doFilter(Request request, Response response) {
		String r=request.getRequestStr().replace("偷盗", "和谐")
		   .replace("抢劫", "帮助");
		request.setRequestStr(r);
	}
}

HTMLFilter:

package cn.edu.hpu.filter.web;

public class HTMLFilter implements Filter {

	@Override
	public void doFilter(Request request, Response response) {
		//先处理带尖括号的信息
		String str=request.getRequestStr().replace('<', '[')
                    .replace('>', ']');
		request.setRequestStr(str);
	}

}

如果我们既想处理request又想处理response,处理反馈这种东西,应该在所有请求处理完毕之后,
再来处理我们这个反馈。因为我们反馈的信息肯定是根据请求最后处理的结果来决定的。

我们先删除掉MsgProcessor.java(因为现在这个类有些多余,不如将东西都放在Main类中去做)

在Main中:

package cn.edu.hpu.filter.web;

public class Main {
	public static void main(String[] args) {
		String msg="大家好:),<script>,偷盗,抢劫,我们要把设计模式学好";
		Request request=new Request();
		request.setRequestStr(msg);
		Response response=new Response();
		//response对象无反馈信息之前先设一个暂时的信息"response"
		response.setResponseStr("response");
		FilterChain fc=new FilterChain();
		fc.addFilter(new HTMLFilter())
		  .addFilter(new SesitiveFilter());//链条式写法

		fc.doFilter(request, response);
		System.out.println(request.getRequestStr());
		System.out.println(response.getResponseStr());
	}
}

测试结果:
大家好:),[script],和谐,帮助,我们要把设计模式学好
response

现在我们只处理了request的信息,还没有处理response的信息

对于request和response我们要求的顺序是这样的:
当我们的一个request传过来的时候,被第一个Filter处理,接下来被第二、第三个Filter处理,
处理完成之后,会有response对象从服务器端反馈信息给我,这个反馈信息被处理的过程是,首先
被第三个进行处理,接下来被第二个处理,最后被第一个处理(有些像堆栈)。

上面说的实现起来要需要一些技巧。

我们先给HTMLFilter和SesitiveFilter类的request和response处理分别加上标记,
来观察一下过滤链的运行顺序:
HTMLFilter:

package cn.edu.hpu.filter.web;

public class HTMLFilter implements Filter {

	@Override
	public void doFilter(Request request, Response response) {
		//先处理带尖括号的信息
		String str=request.getRequestStr().replace('<', '[')
                    .replace('>', ']');
		request.setRequestStr(str+"----HTMLFilter");

		str=response.getResponseStr()+"----HTMLFilter";
		response.setResponseStr(str);
	}

}

SesitiveFilter:

package cn.edu.hpu.filter.web;

public class SesitiveFilter implements Filter {
	@Override
	public void doFilter(Request request, Response response) {
		String r=request.getRequestStr().replace("偷盗", "和谐")
		   .replace("抢劫", "帮助");
		request.setRequestStr(r+"----SesitiveFilter");

		r=response.getResponseStr()+"----SesitiveFilter";
		response.setResponseStr(r);
	}
}

Main的测试结果:
大家好:),[script],和谐,帮助,我们要把设计模式学好----HTMLFilter----SesitiveFilter
response----HTMLFilter----SesitiveFilter

对于request请求这个过滤顺序是对的,但是对于response这个过滤顺序就不是刚刚我们所说的想要的
那种顺序,说明我们不可以在处理request的下面去直接处理response。想要完成这个功能,就需要一些扎实的编程技巧。

我们在Filter接口的doFilter方法中加入FilterChain的参数,这样一来,我们就可以在doFilter方法
中去控制使用FilterChain中各种Filter的顺序了。
Filter:

package cn.edu.hpu.filter.web;

public interface Filter {

	void doFilter(Request request,Response response,FilterChain fc);
}

其他各类加上此参数即可。
当我们处理完request信息之后,我可以拿FilterChain使用。
要改写一下FilterChain,好让它能去主动一个一个调用Filter,而不是像之前
的一次遍历着去处理信息:

package cn.edu.hpu.filter.web;

import java.util.List;
import java.util.ArrayList;

public class FilterChain implements Filter{
	List<Filter> filters=new ArrayList<Filter>();
	//记录运行到哪一个Filter了
	int index=0;

	//返回值是FilterChain只为了在Main中满足链条式的编程
	public FilterChain addFilter(Filter f) {
		this.filters.add(f);
		return this;
	}

	@Override
	public void doFilter(Request request,Response response,FilterChain fc) {
		if(index==filters.size()) return;

		Filter f=filters.get(index);
		index++;
		f.doFilter(request, response, fc);

	}
}

处理完request之后我们马上让FilterChain去调用下一个Filter:

package cn.edu.hpu.filter.web;

public class SesitiveFilter implements Filter {
	@Override
	public void doFilter(Request request, Response response,FilterChain fc) {
		String r=request.getRequestStr().replace("偷盗", "和谐")
		   .replace("抢劫", "帮助");
		request.setRequestStr(r+"----SesitiveFilter");

		fc.doFilter(request, response, fc);

		r=response.getResponseStr()+"----SesitiveFilter";
		response.setResponseStr(r);
	}
}

package cn.edu.hpu.filter.web;

public class HTMLFilter implements Filter {

	@Override
	public void doFilter(Request request, Response response,FilterChain fc) {
		//先处理带尖括号的信息
		String str=request.getRequestStr().replace('<', '[')
                    .replace('>', ']');
		request.setRequestStr(str+"----HTMLFilter");

		fc.doFilter(request, response, fc);

		str=response.getResponseStr()+"----HTMLFilter";
		response.setResponseStr(str);
	}

}

我们来测试Main,测试结果为:
大家好:),[script],和谐,帮助,我们要把设计模式学好----HTMLFilter----SesitiveFilter
response----SesitiveFilter----HTMLFilter

刚好达到我们想要的结果,使response的处理是逆向的(request是从栈顶到站底,response是从栈底到栈顶)!

大家可能还没摸清头脑,我们分析一下:
看Main:

package cn.edu.hpu.filter.web;

public class Main {
	public static void main(String[] args) {
		String msg="大家好:),<script>,偷盗,抢劫,我们要把设计模式学好";
		Request request=new Request();
		request.setRequestStr(msg);
		Response response=new Response();
		//response对象无反馈信息之前先设一个暂时的信息"response"
		response.setResponseStr("response");
		FilterChain fc=new FilterChain();
		fc.addFilter(new HTMLFilter())
		  .addFilter(new SesitiveFilter());//链条式写法

		fc.doFilter(request, response,fc);
		System.out.println(request.getRequestStr());
		System.out.println(response.getResponseStr());
	}
}

我们首先调用的是FilterChain的doFilter方法,这个时候,FilterChain中的index是0,也就是说调用了第一个Filter即HTMLFilter,这个时候在HTMLFilter中处理了request的信息之后(此时是request信息被第一次处理,并且加了标记"----HTMLFilter"),调用了FilterChain的doFilter方法,此时在FilterChain的doFilter方法中又进一步调用了下一个Filter,这样下来,最终调取了最后的SesitiveFilter,在SesitiveFilter中进一步处理了request的信息(此时是request信息被第二次处理,并且加了标记"----SesitiveFilter"),然后继续执行FilterChain的doFilter方法,发现index已经到头了,方法结束,这个时候开始执行下面的处理Response的代码(此时response信息被第一次处理,并且加了标记"----SesitiveFilter"),处理完毕时候跳出了递归,最后又回到了HTMLFilter中,接下去处理response(此时response信息被第二次处理,并且加了标记"----HTMLFilter"),

其实运行一下,仔细思考一下(前提是你理解递归的概念),理解起来并不难。难得的是,JavaWeb中对Servlet的过滤器就是采用类似这种机制来完成请求和反馈的过滤的(其实还不如刚刚我们设计的那种)。

至此责任链就探讨完了,大家是不是也理解了Filter的一些原理?
在此感谢马士兵老师的"设计模式"视频的讲解。

转载请注明出处:http://blog.csdn.net/acmman/article/details/44673483

时间: 2024-11-05 14:47:34

【设计模式】责任链4-链接链的相关文章

iOS设计模式 - 责任链

iOS设计模式 - 责任链   原理图   说明 在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求.发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任.   源码 https://github.com/YouXianMing/iOS-Design-Patterns // // ChainOfResponsibilityProtocol.h // C

iOS应用设计模式开发中职责链(责任链)模式的实现解析_IOS

定义为了避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止,职责链模式又称为责任链模式,它是一种对象行为型模式.(如果你接触过异常处理,那么套用异常处理机制可以更好地理解). 职责链可以是一条直线,也可以是一个环,还可以是一个树形结构,不过最常见的职责链是直线型,即沿着一条单向的链来传递请求.链上的每一个对象都是请求处理者,职责链模式可以将请求的处理者组织成一条链,并使请求沿着链传递,由链上的处理者对请求进行相应的处

设计模式 ( 十二 ) 职责链模式(Chain of Responsibility)(对象行为)

 设计模式(十二)职责链模式(Chain of Responsibility)(对象行为型) 1.概述        你去政府部门求人办事过吗?有时候你会遇到过官员踢球推责,你的问题在我这里能解决就解决,不能解决就推卸给另外个一个部门(对象).至于到底谁来解决这个问题呢?政府部门就是为了可以避免屁民的请求与官员之间耦合在一起,让多个(部门)对象都有可能接收请求,将这些(部门)对象连接成一条链,并且沿着这条链传递请求,直到有(部门)对象处理它为止. 例子1:js的事件浮升机制 例子2: 2.问题

外链查链工具新贵族 SEOMOZ工具

  雅虎yahoo外链查询不了,怎么办?雅虎外链工具关闭后我们还能用什么?外链查链工具新贵族,SEOMOZ工具.那这个工具究竟是如何使用呢?今天来简单的看下: 首先:打开opensiteexplorer.org,输入网址以百度为例:   从最上面,Page Authrity 表示的是页面权重,domain authority表示域名权重,linking root domains表示的是有效链接数(不包括301.nofollow等)total links表示总的外链数量.Fackbook shar

友情链接之白链 黑链 假链详细说明

一.白链     白链不必多说,常规的链接都称之为白链.(例:<a href="http://link.imz5.com">友情链接平台</a>),在交换这类链接时,只需要经常检查,防止一些人品有问题的站长删链就行了. 二.黑链     黑链,简单的说就是利用非正常的手段获取其他网站的外链.一般为黑入别人网站得到管理权限,在网站代码里加上肉眼看不见但搜索引挚可以抓到的链接,黑链说白了就是隐藏链接.黑链作为一个单向链接指向你的网站,权重比较高,而又有好多被挂网站通

什么是区块链的链外交易和链内交易

以比特币为代表的公有区块链系统一直有一个广为诟病的缺点:交易性能低.交易性能低包括两方面:一是交易吞吐量小,二是交易速度慢.交易吞吐量是指系统在单位时间内处理请求的交易数量.交易速度是指系统对交易从提交请求到确认交易成功的平均时间. 在比特币区块链系统中,这两个值低得可怜.交易吞吐量是平均每秒7笔,交易速度是平均1小时能完成交易确认.对比一下一般商业银行的核心系统交易处理能力,交易吞吐量超过每秒2000笔,交易速度基本要达到实时.  正是由于比特币区块链的交易性能太低,很多人认为这个性能缺陷是导

seo其实就是=内链+外链

摘要: 虽然标题是个疑问句,但是答案是肯定的,那就是我的眼里不再只有你,搜索引擎算法的趋势是不完全以外链为主. 做seo的人都知道内链为王,外链为皇,这是大家一直这么认为的,所 虽然标题是个疑问句,但是答案是肯定的,那就是我的眼里不再只有你,搜索引擎算法的趋势是不完全以外链为主. 做seo的人都知道内链为王,外链为皇,这是大家一直这么认为的,所以简单的说seo其实就是=内链+外链,而且更多的人甚至是觉得外链的作用大于内链的.的确,在这之前,我也是这样认为的,至少两者的重要性也是一个级别的.但是,

“链”中“链”让你的网站收获不断

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 "链"中"链"让你的网站收获不断 很久没有到A5发布自己的网站推广经验了,今天就讲一讲链中链的推广手法,希望对大家有启发. 大家都会有这种经历,当进入某一个网站阅读一篇文章的时候,会发现文章里面有不少的链接,如果你需要了解详情或相关内容就会点击其中的链接进入另一篇补充文章,然后在另一篇文章中又会有不少的

超级外链和软文外链 外链提交、图片外链、音乐

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 好几天没写文章了,最近西安的天气很不给力,而且很冷.说实话,本人很怕冷,不怕热.前几天的时候,就把大衣棉衣拿出来穿了,穿的厚厚的,有点傻.罢了,闲话不扯了.对了,还有个事,就是最近西安SEO朱其飞呢,在SEOwhy专区开了个专栏作家,网站地址是http://www.seowhy.com/u/zhuqifei/ 有兴趣的朋友可以帮个忙,说起这个

13、Python与设计模式--责任链模式

一.请假系统 假设有这么一个请假系统:员工若想要请3天以内(包括3天的假),只需要直属经理批准就可以了:如果想请3-7天,不仅需要直属经理批准,部门经理需要最终批准:如果请假大于7天,不光要前两个经理批准,也需要总经理最终批准.类似的系统相信大家都遇到过,那么该如何实现呢?首先想到的当然是if-else-,但一旦遇到需求变动,其臃肿的代码和复杂的耦合缺点都显现出来.简单分析下需求,"假条"在三个经理间是单向传递关系,像一条链条一样,因而,我们可以用一条"链"把他们进