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

时间:2023-02-19 13:51:30

---------------------- 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[]中的过滤规则排序、将过滤器列表写入配置文件使扩展性增强

这样过滤器链就形成了:

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

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

用类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)

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

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

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

流程: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 {

	@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