---------------------- android培训、java培训、期待与您交流! ----------------------
模拟BBS对帖子信息进行处理的过程来理解责任链模式
- 构造责任链
Test类:模拟客户端,发表一个包含多种信息的帖子( 例如:String msg ="中国,被就业<script>,富老一代,:) 躲猫猫,失业,黑领"; )
MsgProcessor类:包含处理帖子信息的逻辑(process())
基于用户角度流程:Test类中将消息传入MsgProcessor,由process()方法返回处理后的结果
process()的处理逻辑(假设过滤掉HTML标记:replaceAll("<","[")
敏感词 replaceAll("失业", "就业") :) replaceAll(":\\)", ":-)") 不健康内容……)
问题:假设不断有新的过滤规则产生,则process()将逐渐变得臃肿,难以维护!
这时可以考虑对过滤规则进行动态指定:将不同的过滤规则封装起来(如:HTMLFilter、SensitiveFilter),统一实现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的引用fc、process()中调用fc的doFilter(msg)
处理流程:MsgProcessor将收到的信息交给FilterChain处理,而FilterChain循环调用每个Filter的doFilter(…)将两个FilterChain合并:因为FilterChain可以看作一个Filter,所以可以将一个FilterChain加入另一个FilterChain:fc.addFilter(fc2)
问题:要求过滤器能同时过滤从客户端接收和从服务器返回的信息
流程:request信息依次经过过滤器Filter1、Filter2,而response信息依次经过Filter2、Filter1(类似堆栈)
若在HTMLFilter的doFilter(……)中处理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 { @Override public 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