黑马程序员:我对责任链模式(Responsibility Chain)的理解

来源:互联网 发布:ug编程培训 编辑:程序博客网 时间:2024/04/18 14:18

---------------------- android培训、java培训、期待与您交流! ----------------------

 

模拟BBS对帖子信息进行处理的过程来理解责任链模式

  1. 构造责任链

Test类:模拟客户端,发表一个包含多种信息的帖子( 例如:String msg ="中国,被就业<script>,富老一代,:) 躲猫猫,失业,黑领"; )

MsgProcessor类:包含处理帖子信息的逻辑(process()

基于用户角度流程:Test类中将消息传入MsgProcessorprocess()方法返回处理后的结果

process()的处理逻辑(假设过滤掉HTML标记:replaceAll("<","[")

敏感词 replaceAll("失业", "就业")                :)  replaceAll(":\\)", ":-)")                          不健康内容……)

问题:假设不断有新的过滤规则产生,则process()将逐渐变得臃肿,难以维护!

这时可以考虑对过滤规则进行动态指定:将不同的过滤规则封装起来(如:HTMLFilterSensitiveFilter),统一实现Filter接口,重写接口中的doFilter()。这时在process()中需要这样调用:new HTMLFilter().doFilter(msg)

这样就实现了动态扩展过滤规则。

问题:怎样将不同的过滤规则组合起来使用、添加新的过滤规则

MsgProcessor中保存一个Filter列表:private Filter[] filters = { new HTMLFilter() };

process()方法处理时循环用每个过滤器处理msg,就达到了组合使用过滤器的效果;若添加新过滤器,只要加入Filter[]即可

此时可以对Filter[]中的过滤规则排序、将过滤器列表写入配置文件使扩展性增强

这样过滤器链就形成了:

问题:怎样合并两条责任链、将一条责任链插入其它链中间?

用类FilterChain将所有过滤器规则Filter封装起来,并可以当作一个增强版的过滤器(Filter)使用

public class FilterChain implements Filter{private List<Filter> filters = new ArrayList<Filter>();public FilterChain addFilter(Filter f) { //这里用到了链条式编程技巧this.filters.add(f); //向FilterChain添加过滤器时可以这样写:return this; //fc.addFilter(new HTMLFilter()).addFilter(new SmileFilter())}public String doFilter(String msg) {for (Filter filter : filters) {msg = filter.doFilter(msg);}return msg;}}

MsgProcessor中去掉Filter[]、持有FilterChain的引用fcprocess()中调用fcdoFilter(msg)
处理流程:MsgProcessor将收到的信息交给FilterChain处理,而FilterChain循环调用每个FilterdoFilter(…)

将两个FilterChain合并:因为FilterChain可以看作一个Filter,所以可以将一个FilterChain加入另一个FilterChain:fc.addFilter(fc2)

问题:要求过滤器能同时过滤从客户端接收和从服务器返回的信息

流程:request信息依次经过过滤器Filter1Filter2,而response信息依次经过Filter2Filter1(类似堆栈

若在HTMLFilterdoFilter(……)中处理request信息的语句后直接加处理response信息的语句,不可行!

解决思路:想方设法让HTMLFilter处理完request信息后显式调用下一个过滤器(假设是SmileFilter)!——既然FilterChain包含所有的Filter,让Filter持有FilterChain的引用:

public class FilterChain implements Filter {private List<Filter> filters = new ArrayList<Filter>();private int index = 0;public FilterChain addFilter(Filter f) {this.filters.add(f);return this;}public void doFilter(Request request, Response response, FilterChain fc) {if (filters.size() == index) {return;}Filter f = filters.get(index);index++;f.doFilter(request, response, fc);}}

而在过滤器具体的处理逻辑中这样写:

public class HTMLFilter implements Filter {@Overridepublic void doFilter(Request request, Response response, FilterChain fc) {request.setMsg(request.getMsg().replaceAll("<", "[").replaceAll(">", "]")+ "---我被HTMLFilter处理了!");fc.doFilter(request, response, fc);response.setMsg(response.getMsg() + "我被HTMLFilter处理了!");}}

而在测试类中调用时:

public class Test {public static void main(String[] args) {String msg = "中国,被就业<script>,富老一代,:) 躲猫猫,失业,黑领";Request request = new Request();request.setMsg(msg);Response response = new Response();response.setMsg("response");FilterChain fc = new FilterChain();fc.addFilter(new HTMLFilter()).addFilter(new SmileFilter());fc.doFilter(request, response, fc);System.out.println(request.getMsg());System.out.println(response.getMsg());}}

就能得到如下的结果:

中国,被就业[script],富老一代,:-) 躲猫猫,失业,黑领---我被HTMLFilter处理了!我被SmileFilter处理了!
response---我被SmileFilter处理了!我被HTMLFilter处理了!

这种过滤器同时处理request和response信息的机制也正是当下很多WEB容器所采用的。


  出错的地方replaceAll( ":\\)",":-)" )  必须写 \\   因为 ) 在正则表达式中有特殊含义

 

总结:说白了,责任链模式就是对某事件的不同处理方式组成一个集合,可以任意定制对事件采用的处理方式。

给它叫“责任链”就是因为在事件的处理过程中,每个Filter都要把处理后的结果传递到下一个Filter,每个Filter都对最终的处理结果“负责任”!

 

 

 

 

 

 

 

 

---------------------- android培训、java培训、期待与您交流! ----------------------

 

 

详细请查看:http://edu.csdn.net/heima

 

原创粉丝点击