Java设计模式:责任链
上一篇 / 下一篇 2012-10-10 13:59:09 / 个人分类:Java
N%A(@+yU^'t0 责任链模式(Chain of Responsibility)的目标是使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。
1OeoB)~5|X I0mZ){;bF~0 在处理用户的请求时可能要根据不同的情况对请求添加不同的处理逻辑,在这时候就可以利用责任链进行设计。当需要添加一个处理逻辑时可以很方便的添加一个处理的节点。
p7Iz)mC6Kb%X2T051Testing软件测试网g Ne)tfe现在我们的需求是处理用户的请求,将用户提交的字符串信息进行层层处理,同时在处理完成之后返回结果时,也要对返回的字符串进行层层处理,而处理返回的情况时其处理的顺序和先前是正好相反的顺序。51Testing软件测试网`*\r-YT)Y#_ LP ^
51Testing软件测试网f.Bg|(h"S }首先建立用户的请求和接收对象Request和Response:51Testing软件测试网5y4Y#Pjnd8js
|
2k(pY7S Q$ve3O0 我们将处理用户信息的逻辑抽象成为一个个的过滤器,进一步抽象出过滤器接口Filter:
!X'{2Spk%Y)g0
|
8Y#f8h;W.H0 注意在Filte接口中doFilter方法参数中有FilterChain的一个变量,我们再建立FilterChain类:51Testing软件测试网7{|*S,R/`5J
- packagecom.lcq.filter;
- 51Testing软件测试网Ha4G`Q$W6r1dz"k
- importjava.util.ArrayList;
- importjava.util.List;
.| |Q%CX(QQZT4a0- publicclassFilterChainimplementsFilter {
- List<Filter> filters =newArrayList<Filter>();
- intindex =0;
- 51Testing软件测试网?"H a3@*k,_,Q#a
- publicFilterChain addFilter(Filter f) {
- this.filters.add(f);
- returnthis;
- }
&@/~vO i.PU1s0- @Override
- publicvoiddoFilter(Request request, Response response, FilterChain chain) {
- if(index == filters.size())
- return;
- Filter f = filters.get(index);
- index++;
- f.doFilter(request, response, chain);
- }
- }
iE{v~I&t051Testing软件测试网8^|4}?&|'[MG在FilterChain中继承了Filter接口,从而实现了doFilter方法,在FilterChain中又有一个index变量,该 变量是用来标记当前访问的是哪一个过滤器,这些过滤器是存放在ArrayList中的,这样用户在使用的时候就可以实现自己的过滤器,编写自己的处理逻 辑,从而将自己的过滤器添加到ArrayList中,再调用FilterChain的doFilter方法遍历整个责任链。51Testing软件测试网vn3[DZjK$e
9g6Y}iWz;g0 下面我们编写三个过滤器:
5W,v/EK"kG7P,f0r uSjps0 HTMLFilter类:
z/~6~ |(z#}+n051Testing软件测试网i_:] aGk-h [;Ykf/Z ZNp-Y0
51Testing软件测试网1p_,Pn S:h5T0zO- packagecom.lcq.filter;
- 51Testing软件测试网jqzv
asVq~:kT
- /**
- * 过滤HTML中的脚本元素
- * @author lcq
- *
- */
- publicclassHTMLFilterimplementsFilter {
- 51Testing软件测试网"? U?8U%Ho(x5q%ve
- @Override
- publicvoiddoFilter(Request request, Response response,FilterChain chain) {
- request.requestStr = request.getRequestStr().replace("<","[")
- .replace(">","] --------HTMLFilter");
- chain.doFilter(request, response, chain);
- response.responseStr +="--------HTMLFilter";
- }
bO!Y{!WE0e\ K*pF7O0- }
SesitiveFilter类:
g8K2P-h+k4[?051Testing软件测试网/T`v}D#ZD OZZQ0D'`0
51Testing软件测试网zOl#_;g2P(B- packagecom.lcq.filter;
- 51Testing软件测试网/ur|2G4Rz'h
- publicclassSesitiveFilterimplementsFilter {
:?sJ,mft#A~0- @Override
- publicvoiddoFilter(Request request, Response response, FilterChain chain) {
- request.requestStr = request.getRequestStr().replace("敏感"," ")
- .replace("猫猫","haha------SesitiveFilter");
- chain.doFilter(request, response, chain);
- response.responseStr +="------SesitiveFilter";
- 51Testing软件测试网6SMF)Wk d
- }
- 51Testing软件测试网5h8qz%m i&^"\.|
- }
FaceFilter类:51Testing软件测试网T)|@U7|q `
51Testing软件测试网.]"_"ZFG0|\UnI|~1?+_W0
51Testing软件测试网K V F'H+[2C3v- packagecom.lcq.filter;
- 51Testing软件测试网n,sY;sHYU
- publicclassFaceFilterimplementsFilter {
- 51Testing软件测试网7f)M'FQOg5P3|
- @Override
- publicvoiddoFilter(Request request, Response response, FilterChain chain) {
- request.requestStr = request.getRequestStr().replace(":)",
- "^V^-------FaceFilter");
- chain.doFilter(request, response, chain);
- response.responseStr +="-------FaceFilter";
Q+bh}!ai1Neh0- }
PRbE:b6Z_%QO0- }
最后编写测试类:51Testing软件测试网(AQBT S9q
51Testing软件测试网,s/?$Q/s ZY&]Jh p`)Q2P.u0
51Testing软件测试网,VD0O.i!_'^&kk- packagecom.lcq.filter;
vVT9jf8G]0- publicclassMain {
- publicstaticvoidmain(String[] args) {
- String message ="敏感词汇,重庆,<script> 躲猫猫 :)";
- Request request =newRequest();
- request.setRequestStr(message);
- Response response =newResponse();
- response.setResponseStr("response");
- FilterChain fc =newFilterChain();
- fc.addFilter(newHTMLFilter()).addFilter(newSesitiveFilter());
- 51Testing软件测试网-i SSv^t9R%r
- FilterChain fc2 =newFilterChain();
- fc2.addFilter(newFaceFilter());
- fc.addFilter(fc2);
- fc.doFilter(request, response,fc);
- System.out.println("request = "+ request.getRequestStr());
- System.out.println("response = "+ response.getResponseStr());
- }
!L3h(W^S*y0- }
在上面的实例中应该注意两个地方:
)g9UTB*o#C~ j051Testing软件测试网 ?4R(G,Hg7}@J1、我们建立的FilterChain中继承了Filter接口,所以在测试类中就可以像使用其他的过滤器一样使用FilterChain,大大提高了灵活性;
oILfYTlU}0] }B;_XM0 2、对于实现责任链的访问处理顺序问题,该问题的解决使用的是递归的思想,从而使先调用的结点在处理返回结果时其调用过滤器的顺序是相反的。这种解决方案在Struts和其他框架中实现过滤器和拦截器使用的较为普遍,并且十分巧妙。