Java设计模式系列之责任链模式
责任链模式
责任链模式是一种对象的行为模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。Tomcat中的Filter就是使用了责任链模式,创建一个Filter除了要在web.xml文件中做相应配置外,还需要实现javax.servlet.Filter接口。
为了方便理解,责任链模式直接用马士兵老师中的一个例子来讲解,做下笔记也方便自己以后的复习查询:
我们有一个字符串String msg = ":):,<script>,敏感,被就业,网络授课";我们希望应用以下三个规则对字符串进行过滤和谐处理:
(1)将字符串中出现的"<>"符号替换成"[]"
(2)处理字符串中的敏感信息,将被就业和谐成就业
(3)将字符串中出现的":):"转换成"^V^";
字符串会依次运用这三条规则,对字符串进行处理,每个规则都有自己需要完成的责任和任务。
第一步:定义封装请求的类Request和封装处理结果响应的类Response
//封装请求的类Request
public class Request {
String requestStr; public String getRequest() {
return requestStr;
} public void setRequest(String request) {
this.requestStr = request;
} }
//封装响应信息的类Response
public class Response {
String responseStr; public String getResponse() {
return responseStr;
} public void setResponse(String response) {
this.responseStr = response;
} }
第二步:定义具有过滤功能的接口Filter,具体的过滤规则需要实现该接口
/*
* 定义接口Filter,具体的过滤规则需要实现这个接口,最后一个参数添加的意义是我们在Main函数中:
* fc.doFilter(request, response,fc);执行这一步的时候可以按照规则链条一次使用三个过滤规则对字符串进行处理
* 因为
*
*/
public interface Filter {
void doFilter(Request request,Response response,FilterChain chain);
}
第三步:定义具体的过滤处理规则
规则一
package com.bjsxt.dp.filter; //处理字符串中的HTML标记
public class HTMLFilter implements Filter { public void doFilter(Request request, Response response,FilterChain chain) {
//将字符串中出现的"<>"符号替换成"[]"
request.requestStr=request.requestStr
.replace('<', '[').replace('>', ']')+
//后面添加的是便于我们观察代码执行步骤的字符串
"----HTMLFilter()";
chain.doFilter(request, response,chain);
response.responseStr+="---HTMLFilter()";
} }
规则二
package com.bjsxt.dp.filter; //定义的过滤敏感字眼的过滤规则
public class SensitiveFilter implements Filter{ public void doFilter(Request request, Response response,FilterChain chain) {
//处理字符串中的敏感信息,将被就业和谐成就业
request.requestStr=request.requestStr
.replace("被就业", "就业").replace("敏感", "")+
//后面添加的是便于我们观察代码执行步骤的字符串
" ---sensitiveFilter()";
chain.doFilter(request, response,chain);
response.responseStr+="---sensitiveFilter()";
} }
规则三:
package com.bjsxt.dp.filter; //定义FaceFilter
public class FaceFilter implements Filter { public void doFilter(Request request, Response response, FilterChain chain) { //将字符串中出现的":):"转换成"^V^";
request.requestStr = request.requestStr.replace(":):", "^V^")
//后面添加的是便于我们观察代码执行步骤的字符串
+ "----FaceFilter()";
chain.doFilter(request, response, chain);
response.responseStr += "---FaceFilter()";
} }
第四步:定义责任链FilterChain
package com.bjsxt.dp.filter; import java.util.ArrayList;
import java.util.List; //过滤链条
public class FilterChain implements Filter{
//用List集合来存储过滤规则
List<Filter> filters = new ArrayList<Filter>();
//用于标记规则的引用顺序
int index=0;
//往规则链条中添加规则
public FilterChain addFilter(Filter f) {
filters.add(f);
//代码的设计技巧:Chain链添加过滤规则结束后返回添加后的Chain,方便我们下面doFilter函数的操作
return this;
}
public void doFilter(Request request,Response response,FilterChain chain){
//index初始化为0,filters.size()为3,不会执行return操作
if(index==filters.size()){
return;
}
//每添加一个过滤规则,index自增1
Filter f=filters.get(index);
index++;
//根据索引值获取对应的规律规则对字符串进行处理
f.doFilter(request, response, chain);
}
}
第五步:测试一下我们的代码
package com.bjsxt.dp.filter; import java.util.ArrayList;
import java.util.List; //过滤链条
public class FilterChain implements Filter{
//用List集合来存储过滤规则
List<Filter> filters = new ArrayList<Filter>();
//用于标记规则的引用顺序
int index=0;
//往规则链条中添加规则
public FilterChain addFilter(Filter f) {
filters.add(f);
//代码的设计技巧:Chain链添加过滤规则结束后返回添加后的Chain,方便我们下面doFilter函数的操作
return this;
}
public void doFilter(Request request,Response response,FilterChain chain){
//index初始化为0,filters.size()为3,不会执行return操作
if(index==filters.size()){
return;
}
//每添加一个过滤规则,index自增1
Filter f=filters.get(index);
index++;
//根据索引值获取对应的规律规则对字符串进行处理
f.doFilter(request, response, chain);
}
}
运行结果:
^V^,[script],,就业,网络授课----HTMLFilter() ---sensitiveFilter()----FaceFilter()
response:---FaceFilter()---sensitiveFilter()---HTMLFilter()
代码可以使用Eclipse中设置断点,debug单步调试去验证,我们下面带着大家一块执行一下上面的代码。
(1)主函数中执行到fc.doFilter(request, response,fc);我们在此处设置断点(Eclipse设置断点的方式:在这行左面,双击那个竖边框的对应位置即可设置断点),现在的执行情况是下面这样,代码上面可以看到执行过程,现在停留在Main.main函数中。

(2)我们点击左上角的Step Into(F5)进入到doFilter(request,response,fc)中

现在执行位置在FilterChain.doFilter,依次执行代码,因为此时的index还是0,因此不可能执行return操作,跳过if代码块,调用索引值为0的规则HTMLFilter,index自增1,执行f.doFilter(request, response, chain);现在进入到了HTMLFilter类中的doFilter方法中

依次执行代码,对字符串请求进行处理,执行到chain.doFilter(request, response,chain)这一句,会再次进入FilterChain中的doFilter方法内

此时的index为1,仍然跳过if代码块执行下面的步骤,和上面一样,用索引值为1的规则进行处理,index自增1现在变成2了。执行f.doFilter(request, response, chain);会进入到SensitiveFilter中的doFilter方法执行

第三个规则的应用和前两个一致,直接给出执行到FaceFilter类中的doFilter方法的结果截图

现在执行到if判断,index的值为3,满足判断条件返回,上图中最上面的函数退栈,回到FaceFilter.doFilter函数中执行response.responseStr += "---FaceFilter()";这就是我们运行结果中response中的第一部分。函数会依次退栈,response不断添加已经做过处理的规则的信息response.responseStr+="---sensitiveFilter()";response.responseStr+="---HTMLFilter()";最终回到Main.main函中打印reponse信息
运行过程用下图表示:

Java设计模式系列之责任链模式的更多相关文章
- 重学 Java 设计模式:实战责任链模式「模拟618电商大促期间,项目上线流程多级负责人审批场景」
作者:小傅哥 博客:https://bugstack.cn - 原创系列专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 场地和场景的重要性 射击
- 《java设计模式》之责任链模式
在阎宏博士的<JAVA与模式>一书中开头是这样描述责任链(Chain of Responsibility)模式的: 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其 ...
- Java设计模式学习记录-责任链模式
前言 已经把五个创建型设计模式和七个结构型设计模式介绍完了,从这篇开始要介绍行为型设计模式了,第一个要介绍的行为型设计模式就是责任链模式(又称职责链模式). 责任链模式 概念介绍 责任链模式是为了避免 ...
- Java设计模式13:责任链模式
前言 来菜鸟这个大家庭10个月了,总得来说比较融入了环境,同时在忙碌的工作中也深感技术积累不够,在优秀的人身边工作必须更加花时间去提升自己的技术能力.技术视野,所以开一个系列文章,标题就轻松一点叫做最 ...
- 《JAVA设计模式》之责任链模式(Chain of Responsibility)
在阎宏博士的<JAVA与模式>一书中开头是这样描述责任链(Chain of Responsibility)模式的: 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其 ...
- Java设计模式十九——责任链模式
责任链模式 老李的苦恼 每个人在出生的时候,都早已在暗中被标好了三六九等. 老李是一名建筑工地的木匠,和大多数生活在社会最底层的农民工一样,一辈子老实本分,胆小怕事.在他们的心中,谁当老爷都没有区别, ...
- Java设计模式之《职责链模式》及应用场景
原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6530089.html 职责链模式(称责任链模式)将请求的处理对象像一条长链一般组合起来,形 ...
- Python使用设计模式中的责任链模式与迭代器模式的示例
Python使用设计模式中的责任链模式与迭代器模式的示例 这篇文章主要介绍了Python使用设计模式中的责任链模式与迭代器模式的示例,责任链模式与迭代器模式都可以被看作为行为型的设计模式,需要的朋友可 ...
- 【java设计模式】之 责任链(chain of resposibility)模式
责任链模式,顾名思义,就是一条链.这个链到底是怎么运行的呢?它主要是将能够处理同一类请求的对象连成一条链,所提交的请求沿着链传递,链上的对象逐个判断是否有能力处理该请求,如果能则处理,如果不能则传递给 ...
随机推荐
- Java解压上传zip或rar文件,并解压遍历文件中的html的路径
1.本文只提供了一个功能的代码 public String addFreeMarker() throws Exception { HttpSession session = request.getSe ...
- html5 touch事件实现触屏页面上下滑动(二)
五一小长假哪都没去,睡了三天,今天晕晕沉沉的投入工作了,但还是做出了一点点效果 上周用html5的touch事件把简单的滑动做出来了,实现了持续页面上下滑动的效果,参考之前 的文章及代码html5 t ...
- UserAccountInfo时间倒计时
界面如下: 代码如下: using System;using System.Collections.Generic;using System.ComponentModel;using System.D ...
- TeeChart显示三维的图形,使用Surface
绘制一个球 根据公式x^2+y^2+z^2=R^2; 令x=RsinAcosB y=RcosAcosB z=RsinB using System; using System.Collections. ...
- openVPN使用
http://www.williamlong.info/archives/3814.html http://openvpn.ustc.edu.cn/ http://www.williamlong.in ...
- 关于BigDecimal的四舍五入和截断 (2007-08-10 15:06:26)
关于四舍五入:ROUND_HALF_UP: 遇到.5的情况时往上近似,例: 1.5 ->;2ROUND_HALF_DOWN : 遇到.5的情况时往下近似,例: 1.5 ->;1 BigDe ...
- MyEclipse中使用JUnit进行单元测试
1. 下载JUnit的jar文件,下载地址在这里 2. 在MyEclipse中新建一个要测试的项目HelloJUnit 3. 添加一个要测试的类HelloJUnit,代码如下,注意需要先建packag ...
- Pod::Executable pull
使用cocoapods 的时候遇到了以下错误:[!] Pod::Executable pull Updating eaf98af..ba3c030 error: Your local changes ...
- ACM - ICPC World Finals 2013 D Factors
原题下载:http://icpc.baylor.edu/download/worldfinals/problems/icpc2013.pdf 题目翻译: 问题描述 一个最基本的算数法则就是大于1的整数 ...
- fil_space_t
typedef struct fil_space_struct fil_space_t; /** Tablespace or log data space: let us call them by a ...