设计模式——责任链

原创 2012年03月23日 15:19:49

责任链模式(Chain of Responsibility)的目标是使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。

在处理用户的请求时可能要根据不同的情况对请求添加不同的处理逻辑,在这时候就可以利用责任链进行设计。当需要添加一个处理逻辑时可以很方便的添加一个处理的节点。

现在我们的需求是处理用户的请求,将用户提交的字符串信息进行层层处理,同时在处理完成之后返回结果时,也要对返回的字符串进行层层处理,而处理返回的情况时其处理的顺序和先前是正好相反的顺序。

首先建立用户的请求和接收对象Request和Response:

package com.lcq.filter;

public class Request {
	String requestStr;

	public String getRequestStr() {
		return requestStr;
	}

	public void setRequestStr(String requestStr) {
		this.requestStr = requestStr;
	}

}

package com.lcq.filter;

public class Response {
	String responseStr;

	public String getResponseStr() {
		return responseStr;
	}

	public void setResponseStr(String responseStr) {
		this.responseStr = responseStr;
	}

}

我们将处理用户信息的逻辑抽象成为一个个的过滤器,进一步抽象出过滤器接口Filter:
package com.lcq.filter;

public interface Filter {
	public void doFilter(Request request, Response response,FilterChain chain);

}

注意在Filte接口中doFilter方法参数中有FilterChain的一个变量,我们再建立FilterChain类:

package com.lcq.filter;

import java.util.ArrayList;
import java.util.List;

public class FilterChain implements Filter {
	List<Filter> filters = new ArrayList<Filter>();
	int index = 0;

	public FilterChain addFilter(Filter f) {
		this.filters.add(f);
		return this;
	}

	@Override
	public void doFilter(Request request, Response response, FilterChain chain) {
		if (index == filters.size())
			return;
		Filter f = filters.get(index);
		index++;
		f.doFilter(request, response, chain);
	}
}

在FilterChain中继承了Filter接口,从而实现了doFilter方法,在FilterChain中又有一个index变量,该变量是用来标记当前访问的是哪一个过滤器,这些过滤器是存放在ArrayList中的,这样用户在使用的时候就可以实现自己的过滤器,编写自己的处理逻辑,从而将自己的过滤器添加到ArrayList中,再调用FilterChain的doFilter方法遍历整个责任链。

下面我们编写三个过滤器:

HTMLFilter类:

package com.lcq.filter;

/**
 * 过滤HTML中的脚本元素
 * @author lcq
 *
 */
public class HTMLFilter implements Filter {

	@Override
	public void doFilter(Request request, Response response,FilterChain chain) {
		request.requestStr = request.getRequestStr().replace("<", "[")
				.replace(">", "] --------HTMLFilter");
		chain.doFilter(request, response, chain);
		response.responseStr += "--------HTMLFilter";
		
	}

}

SesitiveFilter类:

package com.lcq.filter;

public class SesitiveFilter implements Filter {

	@Override
	public void doFilter(Request request, Response response, FilterChain chain) {
		request.requestStr = request.getRequestStr().replace("敏感", "  ")
				.replace("猫猫", "haha------SesitiveFilter");
		chain.doFilter(request, response, chain);
		response.responseStr += "------SesitiveFilter";

	}

}

FaceFilter类:

package com.lcq.filter;

public class FaceFilter implements Filter {

	@Override
	public void doFilter(Request request, Response response, FilterChain chain) {
		request.requestStr = request.getRequestStr().replace(":)",
				"^V^-------FaceFilter");
		chain.doFilter(request, response, chain);
		response.responseStr += "-------FaceFilter";

	}

}

最后编写测试类:

package com.lcq.filter;

public class Main {
	public static void main(String[] args) {
		String message = "敏感词汇,重庆,<script> 躲猫猫 :)";
		Request request = new Request();
		request.setRequestStr(message);
		Response response = new Response();
		response.setResponseStr("response");
		FilterChain fc = new FilterChain();
		fc.addFilter(new HTMLFilter()).addFilter(new SesitiveFilter());

		FilterChain fc2 = new FilterChain();
		fc2.addFilter(new FaceFilter());
		fc.addFilter(fc2);
		fc.doFilter(request, response,fc);
		System.out.println("request = " + request.getRequestStr());
		System.out.println("response = " + response.getResponseStr());
	}

}
在上面的实例中应该注意两个地方:

1.我们建立的FilterChain中继承了Filter接口,所以在测试类中就可以像使用其他的过滤器一样使用FilterChain,大大提高了灵活性;

2.对于实现责任链的访问处理顺序问题,该问题的解决使用的是递归的思想,从而使先调用的结点在处理返回结果时其调用过滤器的顺序是相反的。这种解决方案在Struts和其他框架中实现过滤器和拦截器使用的较为普遍,并且十分巧妙。










版权声明:本文为博主原创文章,未经博主允许不得转载。

Java设计模式之责任链模式、职责链模式

继续介绍23种设计模式系列,本文介绍的是职责链模式。
  • jason0539
  • jason0539
  • 2015年04月18日 07:41
  • 25000

Java模式之责任链模式

从请假开始谈起 话说上次五一请假回去玩了一个多星期,期间回了一次老家,去了一趟武汉,接着又跑到了景德镇,和庐山;玩的好不自在;但是想起来上次请假的经历另我记忆犹新啊,算起来也是一波三折吧; 记...
  • liaodehong
  • liaodehong
  • 2016年05月14日 22:19
  • 1716

Java模式开发之责任链模式

从击鼓传花谈起  击鼓传花是一种热闹而又紧张的饮酒游戏。在酒宴上宾客依次坐定位置,由一人击鼓,击鼓的地方与传花的地方是分开的,以示公正。开始击鼓时,花束就开始依次传递,鼓声一落,如果花束在某人手中,则...
  • lizl
  • lizl
  • 2005年07月26日 14:34
  • 7377

Java设计模式----责任链模式

简述:     前端时间再看一些类库的源码,发现责任链模式的强大之处,尤其是和建造者模式的结合后强大的动态可扩展性更是牛逼的一塌糊涂。接下来赶紧了解一下吧!     我们先来了解一下什么是责任...
  • u012810020
  • u012810020
  • 2017年05月05日 12:50
  • 592

java 责任链模式

前言 责任链感觉用的也不少,尤其是当各种系统启动的时候,要初始化好多东西,并且这些启动都是有一定的顺序,谁在前,谁在后,谁是必须启动的,谁是暂时可以不启动的;还有就是web请求过来的时候,需要一级级...
  • qq_22912803
  • qq_22912803
  • 2016年08月03日 14:42
  • 194

《JAVA与模式》之责任链模式

在阎宏博士的《JAVA与模式》一书中开头是这样描述责任链(Chain of Responsibility)模式的:   责任链模式是一种对象的行为模式。在责任链模式里,很多对象由每一个对象对其下...
  • zhouyong0
  • zhouyong0
  • 2012年08月26日 17:00
  • 32244

设计模式:Filter过滤器

场景1: 每种Filter进行某种处理,将各个Filter连在一起形成一个FilterChain。当需要往FilterChain中加入新的Filter,或者改变各个Filter的处理顺序时,可以方便...
  • u011697278
  • u011697278
  • 2016年12月18日 21:06
  • 637

【设计模式】Filter-Chain 的应用

Filter-Chain模式简介 从7月份实习以来,因为项目中运用alibaba DRUID 数据库中间件、Spring Framwork等开源框架,所以就稍微阅读了部分源码,果然优秀的架构就是优秀...
  • u010359884
  • u010359884
  • 2015年11月08日 22:16
  • 1732

java之责任链模式

责任链模式是一种对象的行为模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个...
  • Raynaing
  • Raynaing
  • 2016年05月02日 19:42
  • 348

责任链模式_javaDemo

  • 2014年11月26日 23:15
  • 7KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:设计模式——责任链
举报原因:
原因补充:

(最多只允许输入30个字)