The Chain Of Responsibility (1)
今天分享一下,设计模式中的责任链模式,其余的不过多叙述。
思路
在正式接触责任连之前,我们可以想象到的应该是一个链,链表?要处理一件事需要一个链似得?其实答案差不多就是这样。设计模式也都是从朴素的思维中经过一系列的总结得到的。下面来谈一谈责任链的进化之路。
来源
责任链也是从实际的开发中不断升华得到的一个“套路”,这也是称之为“模式”的原因了。比如说,我们现在要对用户上传的数据进行过滤。要实现这样的一个功能,我们首先想到的可能是下面这样的。
// 待处理的用户的输入数据
String message = "<script>while(1){alert('HaHa,敏感词,替换词')</script>";
String result = message.replaceAll("<","[");
result = result.replaceAll(">","]");
System.out.println("未被处理的数据为:" + message);
System.out.println("经过处理的数据为:" + result);
很简单了吧,但是想一想,这样真的够了吗?
其实String类的设计就是一个链的模式,这点我们可以从replaceAll方法中看出一点端倪。
加大点难度
现在假如说添加了一个更加高级点的功能,那就是实现对HTML的代码的转义,敏感词的过滤,替换词的替换等等。那么如果我们还这样写的话,这个方法体就会变的很大,而且不容易进行维护。而根据面向对象的思维,我们不难想到抽象出一个接口,要想实现哪种功能,就直接让其实现这个接口完成相应的业务逻辑就好了嘛。
下面我们就来看看这种实现。
首先是接口:Filter.java
package ResponsibilityChain;
public interface Filter {
public String doFilte(String message);
}
HTMLFilter.java
package ResponsibilityChain;
/**
* HTML filter utility.
*
* 但是也添加了一些修改内容
*
* @author Craig R. McClanahan
* @author Tim Tye
*/
public final class HTMLFilter implements Filter{
/**
* Filter the specified message string for characters that are sensitive in
* HTML. This avoids potential attacks caused by including JavaScript codes
* in the request URL that is often reported in error messages.
*
* @param message
* The message string to be filtered
*/
public String doFilte(String message) {
if (message == null)
return (null);
char content[] = new char[message.length()];
message.getChars(0, message.length(), content, 0);
StringBuilder result = new StringBuilder(content.length + 50);
for (int i = 0; i < content.length; i++) {
switch (content[i]) {
case '<':
result.append("<");
break;
case '>':
result.append(">");
break;
case '&':
result.append("&");
break;
case '"':
result.append(""");
break;
default:
result.append(content[i]);
}
}
return (result.toString());
}
}
SesitiveFilter.java
package ResponsibilityChain;
public final class SesitiveFilter implements Filter {
@Override
public String doFilte(String message) {
// 正常来说应该是个词库的,对词库中的数据进行匹配,这样比较合理一些,此处为了掩饰核心思想,就简化了这个操作
String str = message.replaceAll("敏感词", "不敏感了");
return str;
}
}
ReplacableFilter.java
package ResponsibilityChain;
public class ReplacableFilter implements Filter {
@Override
public String doFilte(String message) {
// 正常来说应该是个词库的,对词库中的数据进行匹配,这样比较合理一些,此处为了掩饰核心思想,就简化了这个操作
String str = message.replaceAll("替换词", "已被替换");
return str;
}
}
然后是一个业务逻辑的管家了,它负责接收要进行过滤的数据,并且返回处理过的数据,MyProcessor.java
package ResponsibilityChain;
public class MyProcessor {
private String msg;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String process() {
// 调用相关的过滤器进行词汇的过滤
HTMLFilter htmlFilter = new HTMLFilter();
String result = htmlFilter.doFilte(msg);
// 调用敏感词过滤器
SesitiveFilter sesitiveFilter = new SesitiveFilter();
result = sesitiveFilter.doFilte(result);
ReplacableFilter replacableFilter = new ReplacableFilter();
result = replacableFilter.doFilte(result);
return result;
}
}
最后来个测试吧。Main.java
package ResponsibilityChain;
public class Main {
public static void main(String[] args) {
// 待处理的用户的输入数据
String message = "<script>while(1){alert('HaHa,敏感词,替换词')</script>";
MyProcessor myProcessor = new MyProcessor();
myProcessor.setMsg(message);
String result = myProcessor.process();
System.out.println("未被处理的数据为:" + message);
System.out.println("经过处理的数据为:" + result);
}
}
小总结
这样就可以实现我们需要的功能了,我们可以在MyProcessor类中添加我们的过滤器,完成所有我们需要的功能。但是看一下,
public String process() {
// 调用相关的过滤器进行词汇的过滤
HTMLFilter htmlFilter = new HTMLFilter();
String result = htmlFilter.doFilte(msg);
// 调用敏感词过滤器
SesitiveFilter sesitiveFilter = new SesitiveFilter();
result = sesitiveFilter.doFilte(result);
ReplacableFilter replacableFilter = new ReplacableFilter();
result = replacableFilter.doFilte(result);
return result;
}
这段代码,总是感觉有点冗余,给人的感觉就是有点笨重了。下面我们就来解决一下这个问题。
责任链前身
为了解决上面的代码过于冗余,下面引入了责任链的前身,那就是使用一个数组保存我们所有的Filter的实现类,用于管理我们的过滤任务。我们只需要在MyProcessor类中进行修改即可。
如下,MyProcessor2.java
package ResponsibilityChain;
public class MyProcessor2 {
Filter[] filters = { new HTMLFilter(), new SesitiveFilter(), new ReplacableFilter() };
private String msg;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String process() {
String result = msg;
for (Filter f : filters) {
result = f.doFilte(result);
}
return result;
}
}
测试一下:
package ResponsibilityChain;
public class Main2 {
public static void main(String[] args) {
// 待处理的用户的输入数据
String message = "<script>while(1){alert('HaHa,敏感词,替换词')</script>";
MyProcessor2 myProcessor2 = new MyProcessor2();
myProcessor2.setMsg(message);
String result = myProcessor2.process();
System.out.println("未被处理的数据为:" + message);
System.out.println("经过处理的数据为:" + result);
}
}
小总结:这里我们明显的可以看到使用了数组来进行管理的好处了吧,我们只需要在添加新的过滤器实现类的时候在这个数组里面就可以了。
这样看着,有点意思了吧。
责任链出山
看完了上面的代码,想必对这个业务逻辑很熟悉了吧。但是这还不是我们的责任链模式,没有体现出“链”的特点,而且假如说我们有两个这样的数组,要合作的完成过滤任务,而且是在一个完成一半的时候插入另一个数组的任务,这样的话,就比较的棘手了吧。所以下面要交给责任链来进行管理了。
FilterChain.java
package ResponsibilityChain;
import java.util.ArrayList;
import java.util.List;
public class FilterChain implements Filter{
private List<Filter> filters = new ArrayList<Filter>();
/**
* return itself for better usage the Chain
*
* @param f
* @return
*/
public FilterChain addFilter(Filter f) {
filters.add(f);
return this;
}
public void remove(Filter f) {
filters.remove(f);
}
/**
* For the chain , it's also a chain for filter
*
* @param message
* message need to be filtered
* @return
*/
public String doFilte(String message) {
String result = message;
for (Filter f : filters) {
result = f.doFilte(result);
}
return result;
}
}
这样一来,MyProcessor也要进行修改,如MyProcessor3.java
package ResponsibilityChain;
public class MyProcessor3 {
private FilterChain filterChain;
public FilterChain getFilterChain() {
return filterChain;
}
public void setFilterChain(FilterChain filterChain) {
this.filterChain = filterChain;
}
private String msg;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
// 此处为核心and关键
public String process() {
String result = msg;
result = filterChain.doFilte(result);
return result;
}
}
再来测试一把,Main3.java
package ResponsibilityChain;
public class Main3 {
public static void main(String[] args) {
// 待处理的用户的输入数据
String message = "<script>while(1){alert('HaHa,敏感词,替换词')</script>";
MyProcessor3 myProcessor3 = new MyProcessor3();
myProcessor3.setMsg(message);
FilterChain filterChain = new FilterChain();
// filterChain.addFilter(new HTMLFilter());
// filterChain.addFilter(new SesitiveFilter());
// filterChain.addFilter(new ReplacableFilter());
myProcessor3.setFilterChain(filterChain);
// 作为一个链的方式进行添加过滤器,这就是链式编程的好处
filterChain.addFilter(new HTMLFilter()).addFilter(new SesitiveFilter()).addFilter(new ReplacableFilter());
String result = filterChain.doFilte(message);
System.out.println("未被处理的数据为:" + message);
System.out.println("经过处理的数据为:" + result);
}
}
这里就需要好好的来个总结了,经典的思想总是让人感叹啊。
不知道你有没有注意到在FilterChain.java中
public FilterChain addFilter(Filter f) {
filters.add(f);
return this;
}
这个方法就可以完成“链”的效果。返回自身,这样就可以不断的调用同样的方法,链式的完成任务。
还有FilterChain也有一个doFilte的方法,也就是说我们将完成过滤的功能从MyProcessor.java类中迁移到了FilterChain类中了。
而且实现了Filter接口的FilterChain也就可以完成添加更加自由的过滤规则了。
这就是面向对象的核心,一个对象能完成什么功能完全取决于其自身的属性。
这样我们在MyProcessor3.java中只需要调用责任链的这个过滤功能就可以了。
总结
本文从一个现实中的问题出发,从简单的朴素的思想,一步步的经过面向对象的强化以及经典的责任链思想的牵引。完成了一个简单的责任链模式的小例子。
如果细心的品味一下,肯定会有不少感触的吧。责任链模式在实际的开发过程中也是很常见的,比如说Struts2的拦截器栈等等。
The Chain Of Responsibility (1)的更多相关文章
- 责任链模式/chain of responsibility/行为型模式
职责链模式 chain of responsibility 意图 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处 ...
- C#设计模式系列:职责链模式(Chain of Responsibility)
1.职责链模式简介 1.1>.定义 职责链模式是一种行为模式,为解除请求的发送者和接收者之间的耦合,而使多个对象都有机会处理这个请求.将这些对象连接成一条链,并沿着这条链传递该请求,直到有一个对 ...
- 职责链(Chain of Responsibility)模式在航空货运中的运用实例
设计模式这东西,基本上属于“看懂一瞬间,用会好几年”.只有实际开发中,当某一模式很好的满足了业务需求时,才会有真切的感觉.借用一句<闪电侠>中,绿箭侠教导闪电侠的台词:“不是你碰巧遇到了它 ...
- 深入浅出设计模式——职责链模式(Chain of Responsibility Pattern)
模式动机 职责链可以是一条直线.一个环或者一个树形结构,最常见的职责链是直线型,即沿着一条单向的链来传递请求.链上的每一个对象都是请求处理者,职责链模式可以将请求的处理者组织成一条链,并使请求沿着链传 ...
- 设计模式之美:Chain of Responsibility(职责链)
索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):实现后继者链. 意图 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系. 将这些对象连成一条链,并沿着这条 ...
- atitit.设计模式(1)--—职责链模式(chain of responsibility)最佳实践O7 日期转换
atitit.设计模式(1)---职责链模式(chain of responsibility)最佳实践O7 日期转换 1. 需求:::日期转换 1 2. 可以选择的模式: 表格模式,责任链模式 1 3 ...
- 设计模式:职责链模式(Chain Of Responsibility)
定 义:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止. 结构图: 处理请求类: //抽象处理类 abs ...
- 二十四种设计模式:责任链模式(Chain of Responsibility Pattern)
责任链模式(Chain of Responsibility Pattern) 介绍为解除请求的发送者和接收者之间耦合,而使多个对象都有机会处理这个请求.将这些对象连成一条链,并沿着这条链传递该请求,直 ...
- 设计模式 - chain of Responsibility
Chain of Responsibility也就是职责链模式,通过使用链式结构,使对象都有机会处理请求,从而避免请求的发送者与接受者间的耦合关系.将这些对象连成链,并沿着该链传递请求,直到有对象处理 ...
- [学习笔记]设计模式之Chain of Responsibility
为方便读者,本文已添加至索引: 设计模式 学习笔记索引 写在前面 最近时间比较紧,所以发文的速度相对较慢了.但是看到园子里有很多朋友对设计模式感兴趣,我感觉很高兴,能够和大家一起学习这些知识. 之前的 ...
随机推荐
- UVA11082:Matrix Decompressing
题意:给定一个矩阵的前i行的和,以及前i列的和,求任意一个满足条件的矩阵,矩阵元素在[1,20] 矩阵行列<=20 题解:做一个二分图的模型,把行列拆开,然后设源点到行节点的容量就是该行所有元素 ...
- 51nod 1103 N的倍数(抽屉原理)
1103 N的倍数 题目来源: Ural 1302 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 一个长度为N的数组A,从A中选出若干个数,使得这些数的和是N的倍 ...
- hdu 3065 AC自动机(各子串出现的次数)
病毒侵袭持续中 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
- 抽象方法不能是static或native或synchroniz
abstract 是抽象了,只有声明,没有具体的实现方法 static是静态的,是一种属于类而不属于对象的方法或者属性,而我们知道,类其实也是一个对象,他是在class文件加载到虚拟机以后就会产生的对 ...
- C++是跨平台的语言
最开始学习Java时,老师就说Java是跨平台的,而c++不是,这里要纠正一下观点,c++也是跨平台的,只不过是实现跨平台的方式不同而已. 1.平台 一般我们把CPU处理器与操作系统的整体叫平台.不同 ...
- 解决win10 VC++6.0 应用程序无法正常运行 0xc0000142
废话不多说,无法正常运行原因就是win10不兼容中文版的vc,解决方法就是一句话,用英文版的msdev.exe替换中文版的msdev.exe,msdev.exe是vc的启动程序.直接上来教你怎么做.废 ...
- h5的input的required使用中遇到的问题
form提交时隐藏input发生的错误 问题描述 在form表单提交的时候,有些input标签被隐藏,表单验证过程中会出现An invalid form control with name='' is ...
- html下载excel模板
只需要href等于模板存放的路径即可 <a href="../../TempLate/Attitude.xlsx" class="easyui-linkbutton ...
- java 反射机制 观点
反射,当时经常听他们说,自己也看过一些资料,也可能在设计模式中使用过,但是感觉对它没有一个较深入的了解,这次重新学习了一下,感觉还行吧! 一,先看一下反射的概念: 主要是指程序可以访问,检测和修改它本 ...
- 安装Leanote极客范的云笔记
前言 在这个互联网知识呈爆炸增长的时代,作为一个程序员要掌握的知识越来越多,然再好的记性也不如烂笔头,有了笔记我们就是可以时常扒拉扒拉以前的知识,顺便可以整理下自己的知识体系. 如今市面上云笔记产品, ...