责任链模式

责任链模式是一种对象的行为模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。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设计模式系列之责任链模式的更多相关文章

  1. 重学 Java 设计模式:实战责任链模式「模拟618电商大促期间,项目上线流程多级负责人审批场景」

    作者:小傅哥 博客:https://bugstack.cn - 原创系列专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 场地和场景的重要性 射击

  2. 《java设计模式》之责任链模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述责任链(Chain of Responsibility)模式的: 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其 ...

  3. Java设计模式学习记录-责任链模式

    前言 已经把五个创建型设计模式和七个结构型设计模式介绍完了,从这篇开始要介绍行为型设计模式了,第一个要介绍的行为型设计模式就是责任链模式(又称职责链模式). 责任链模式 概念介绍 责任链模式是为了避免 ...

  4. Java设计模式13:责任链模式

    前言 来菜鸟这个大家庭10个月了,总得来说比较融入了环境,同时在忙碌的工作中也深感技术积累不够,在优秀的人身边工作必须更加花时间去提升自己的技术能力.技术视野,所以开一个系列文章,标题就轻松一点叫做最 ...

  5. 《JAVA设计模式》之责任链模式(Chain of Responsibility)

    在阎宏博士的<JAVA与模式>一书中开头是这样描述责任链(Chain of Responsibility)模式的: 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其 ...

  6. Java设计模式十九——责任链模式

    责任链模式 老李的苦恼 每个人在出生的时候,都早已在暗中被标好了三六九等. 老李是一名建筑工地的木匠,和大多数生活在社会最底层的农民工一样,一辈子老实本分,胆小怕事.在他们的心中,谁当老爷都没有区别, ...

  7. Java设计模式之《职责链模式》及应用场景

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6530089.html 职责链模式(称责任链模式)将请求的处理对象像一条长链一般组合起来,形 ...

  8. Python使用设计模式中的责任链模式与迭代器模式的示例

    Python使用设计模式中的责任链模式与迭代器模式的示例 这篇文章主要介绍了Python使用设计模式中的责任链模式与迭代器模式的示例,责任链模式与迭代器模式都可以被看作为行为型的设计模式,需要的朋友可 ...

  9. 【java设计模式】之 责任链(chain of resposibility)模式

    责任链模式,顾名思义,就是一条链.这个链到底是怎么运行的呢?它主要是将能够处理同一类请求的对象连成一条链,所提交的请求沿着链传递,链上的对象逐个判断是否有能力处理该请求,如果能则处理,如果不能则传递给 ...

随机推荐

  1. 【转载】String、StringBuffer与StringBuilder之间区别

    文章来源:http://www.cnblogs.com/A_ming/archive/2010/04/13/1711395.html 这两天在看Java编程的书,看到String的时候将之前没有弄懂的 ...

  2. Fucking "pkg-config not found"

    If you got pkg-config not found error in gnu auto tools then, you must install the related librarys ...

  3. Collection_Compare

    冒泡 package com.bjsxt.sort.bubble; import java.util.Arrays; public class BubbleSort1 { /** * @param a ...

  4. HDFS小文件处理——Mapper处理

    处理小文件的时候,可以通过org.apache.hadoop.io.SequenceFile.Writer类将所有文件写出到一个seq文件中. 大致流程如下: 实现代码: package study. ...

  5. chrome控制台小技巧

    对于大多数开发人员来说,chrome控制台最常用的命令就是 console.log()了,然后还有一些其他类似的命令,如: console.info()   提示信息 console.error() ...

  6. poj 3277 City Horizon (线段树 扫描线 矩形面积并)

    题目链接 题意: 给一些矩形,给出长和高,其中长是用区间的形式给出的,有些区间有重叠,最后求所有矩形的面积. 分析: 给的区间的范围很大,所以需要离散化,还需要把y坐标去重,不过我试了一下不去重 也不 ...

  7. hibernate 中id生成策略

    数据库的设计和操作中,我们通常会给表建立主键. 主键,可以分为自然主键和代理主键. 自然主键表示:采用具有业务逻辑含义的字段作为表的主键.比如在用户信息表中,采用用户的身份证号码作为主键.但是这样一来 ...

  8. ASP.NET MVC ActionResult的实现

    1.11种ActionResult 在System.Web.Mvc命名空间下: ActionResult是一个抽象类, 在Action中返回的都是其派生类.下面是我整理的ASP.NET MVC 1.0 ...

  9. HTTP请求头host解析

    Host: 域名 Host表示请求的服务器网址:   request headers中的host字段 例如有user.xiaoqiang.com,hotel.xiaoqiang.com 现在需要登录后 ...

  10. 深入理解移动web开发之PPI,Pixel,DevicePixelRatio(转)

    如果你是一个开始接触移动Web开发的前端工程师,那么你或许也遇到了和我曾经遇到的过问题:有太多新的概念需要掌握,太多相似的概念需要区分.没关系,我将用两篇文章的篇幅来解决这些问题.上篇文章关于解释和区 ...