责任链模式(CHAIN OF RESPONSIBILITY),通过将多个对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它,属于对象行为型模式。责任链模式使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。JavaScript的事件处理,工作流系统中公文的多级审批,Web开发中的过滤器和拦截器都可以采用责任链模式实现。
一、使用场景
1、有多个对象可以处理同一个请求,具体哪个对象处理该请求需要等到运行时刻再确定。
2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
3、可动态指定一组对象处理请求,客户端可以动态创建职责链来处理请求,还可以改变链中处理者之间的先后次序。
二、UML图

三、Java实现
package study.patterns.chainofresponsibility;
import java.util.ArrayList;
import java.util.List;
/**
* 对于实现责任链的访问处理顺序问题,该问题的解决使用的是递归的思想,从而使先调用的结点在处理返回结果时其调用过滤器的顺序是相反的。
* 这种解决方案在Struts和其他框架中实现过滤器和拦截器使用的较为普遍,并且十分巧妙。
* @author qbg
* 此处通过实现Web中经常采用的过滤器来演示责任链模式的原理和用法。
*/
public class ChainOfResponsibilityPattern {
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);//由于FilterChain也实现Filter接口,所以可以将一个FilterChain加入到另一个FilterChain中
fc.doFilter(request, response,fc);
System.out.println("request = " + request.getRequestStr());
System.out.println("response = " + response.getResponseStr());
}
}
/**
* 封装请求
*/
class Request {
String requestStr;
public String getRequestStr() {
return requestStr;
}
public void setRequestStr(String requestStr) {
this.requestStr = requestStr;
}
}
/**
* 响应:封装请求经过责任链后的处理结果
*/
class Response {
String responseStr;
public String getResponseStr() {
return responseStr;
}
public void setResponseStr(String responseStr) {
this.responseStr = responseStr;
}
}
/**
* 过滤器接口
*/
interface Filter {
public void doFilter(Request request, Response response,FilterChain chain);
}
/**
* 过滤器链
*/
class FilterChain implements Filter {
List
filters = new ArrayList
();//存放所有过滤器集合 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); } } /** * 过滤HTML中的脚本元素 * */ 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"; } } /** * 过滤敏感词 */ 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"; } } /** * 过滤表情符 */ 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"; } }
request = 词汇,重庆,[script] --------HTMLFil