设计模式之责任链模式

来源:互联网 发布:知乎下载电脑版 编辑:程序博客网 时间:2024/05/29 15:14

如有转载,请申明:

转载至 http://blog.csdn.net/qq_35064774/article/details/52102422


1 什么是责任链

 

责任链模式是一种对象的行为模式。

在责任链模式中,很多对象由每一个对象对其下家的引用而接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。客户并不知道链上的哪一个对象最终处理这个请求,系统可以在不影响客户端的情况下动态的重新组织链和分配责任。处理者有两个选择:承担责任或者把责任推给下家。一个请求可以最终不被任何接收端对象所接受。

 

举个简单的例子,很多工厂都是流水线式的生产,一个产品的生产要经过很多道工序,这就形成了一条链式结构。每道工序都是一个单独的处理过程,如果产品出了问题,就挑出来,否则就传到下一个工序。


2 责任链的分类

 

实际上,责任链分为纯责任链和不纯责任链。

纯责任链要求每个处理者要么处理要么直接传给下一个处理者。

而不纯责任链则可以处理一部分之后传给下一个处理者。

 

最常见的当然是不纯责任链,上面举的工厂生产的例子就是这样的。

 

 

 

3 怎么实现责任链

 

为了方便理解,我们通过一个问题来入手。

 

 * 现有一串文本需要发送,然后返回一个结果。

 * 但为了防止文本中含有敏感词汇,我们需要对文本进行过滤。

 * 过滤规则很简单:把<>替换成全角的<>;把“草泥马”、“敏感”替换成相应个数的"*"

 * 要求发送文本和返回结果都需要处理,且形成一条链式的顺序,即 发送文本是先通过 过滤规则1、过滤规则2,而返回结果是通过 过滤规则2、过滤规则1

 

 

拿到这个问题,大致的思路是,先造出一个容器,存储过滤规则,然后通过循环来处理文本。

为了代码有个整体轮廓,这次先写测试代码。

 

package com.ittianyu.chain;public class Test {public static void main(String[] args) {// 先造一个责任链容器FilterChain chain = new FilterChain();// 往责任链容器中添加过滤规则chain.addFilter(new HtmlFlagFilter()).addFilter(new SensitiveFilter());// 先假设我们的请求和结果文本是这样的Request request = new Request("啊哈哈哈哈 <html> 草泥马 敏感 sssss </html>");Response response = new Response("请求处理成功");// 开始过滤chain.doFilter(request, response, chain);// 输出结果System.out.println(request.getString());System.out.println(response.getString());}}


大致处理过程就是如上了。然后我们开始制作责任链容器。他应该有addFilterdoFilter方法。

 

package com.ittianyu.chain;import java.util.ArrayList;import java.util.List;public class FilterChain implements Filter {private List<Filter> filters = new ArrayList<Filter>();private int index = 0;// 添加一条处理规则public FilterChain addFilter(Filter filter) {filters.add(filter);return this;}/** * 处理下一个过滤规则 */@Overridepublic void doFilter(Request request, Response response, FilterChain chain) {if(index >= filters.size())return;Filter filter = filters.get(index);index++;filter.doFilter(request, response, chain);}}

 

稍微难想到的是doFilter方法,因为是责任链,所以不能一次性循环处理完,这样就没有链的过滤意义了。

 

FilterChain 里面我们实现了Filter接口,还是使用了其中的方法doFilter,所以还需要造一个Filter接口。

 

package com.ittianyu.chain;public interface Filter {void doFilter(Request request, Response response, FilterChain chain);}


你会发现Request Response,这两个类其实很简单的,让你看一下它的实现。

 

package com.ittianyu.chain;public class Request {public String string;public String getString() {return string;}public void setString(String string) {this.string = string;}public Request(){}public Request(String string) {super();this.string = string;}}


package com.ittianyu.chain;public class Response {public String string;public String getString() {return string;}public void setString(String string) {this.string = string;}public Response(){}public Response(String string) {super();this.string = string;}}


其实里面就只有一个字符串。

 

有了Filter接口,我们还需要实现了接口的过滤类。

首先是对<>的过滤类

 

package com.ittianyu.chain;public class HtmlFlagFilter implements Filter {@Overridepublic void doFilter(Request request, Response response, FilterChain chain) {// 先处理请求request.string = filter(request.string);// 交给下一个处理者chain.doFilter(request, response, chain);// 后处理结果response.string = filter(response.string);}/** * 把<>替换成全角的 * @param string 需要过滤的文本 * @return 返回过滤后的文本 */private String filter(String string) {string = string.replaceAll("<", "<").replaceAll(">", ">");string += "\n---deal by HtmlFlagFilter---\n";return string;}}

 

需要注意的是doFilter中,先对request进行过滤,然后马上就调用chain.doFilter进行下一条规则的过滤,这样就可以在其他规则处理完成后,才处理返回结果,这样就满足的问题的要求。

同样的,还有对敏感词的过滤规则。

 

package com.ittianyu.chain;public class SensitiveFilter implements Filter {@Overridepublic void doFilter(Request request, Response response, FilterChain chain) {// 先处理请求request.string = filter(request.string);// 交给下一个处理者chain.doFilter(request, response, chain);// 后处理结果response.string = filter(response.string);}private String filter(String string) {string = string.replaceAll("敏感", "**").replaceAll("草泥马", "***");string += "\n---deal by SensitiveFilter---\n";return string;}}


 

到此这个例子就写完了,不信试一下。

 

当然这个例子并没有很好的体现责任链的使用,比如这个例子我们还可以改成,当发现敏感词时,就停止处理了,也就是不交给下一个过滤规则。

 

 

 

4 在什么情况下使用责任链模式

 

 * 有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。

 * 在不明确指定接受者的情况下,向多个对象中的一个提交一个请求。

 * 可动态指定一组对象处理请求。

 

 

5 责任链模式的优点和缺点

 

优点:

 * 降低耦合度。

 * 简化对象的相互连接。

 * 增强给对象指派职责的灵活性。

 * 增加新的请求处理类很方便。

 

 

缺点:

 * 不能保证请求一定被接收。

 * 系统性能将受到一定影响,而且在进行代码调试时不太方便。

 

1 0
原创粉丝点击