责任链模式(CHAIN OF RESPONSIBILITY),通过将多个对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它,属于对象行为型模式。责任链模式使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。JavaScript 的事件处理,工作流系统中公文的多级审批,Web开发中的过滤器和拦截器都可以采用责任链模式实现。
一、使用场景
1、有多个对象可以处理同一个请求,具体哪个对象处理该请求需要等到运行时刻再确定。 2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。 3、可动态指定一组对象处理请求,客户端可以动态创建职责链来处理请求,还可以改变链中处理者之间的先后次序。
二、UML图
三、Java 实现
package study.patterns.chainofresponsibility; import java.util.ArrayList; import java.util.List; 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); 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<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); } } 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] --------HTMLFilter 躲haha------SesitiveFilter ^V^-------FaceFilter response = response-------FaceFilter------SesitiveFilter--------HTMLFilter
四、模式优缺点
优点:
1、降低耦合度。职责链模式将请求处理细节(请求由哪些对象处理,怎样处理)跟客户端代码隔离开来,这些细节对客户端是透明的,客户端只需将相应的职责添加到链中即可,具体的处理过程交给责任链,降低了系统的耦合度。
2、增强了给对象指派职责的灵活性。可以通过在运行时对职责链进行动态的增加或修改来改变处理一个请求的职责,职责链的维护是客户端负责的,所以增加或修改责任链不影响类库代码,非常灵活。
缺点:
1、不保证请求被接受。由于责任链中的每个对象只处理自己感兴趣的请求,对于请求是否处理过并没有感知,这样容易导致请求没有对应的处理者。当一个请求的责任链没有正确配置时也会导致该请求得不到处理。
2、由于责任链模式请求处理的不确定性,所以加大了程序调试的难度。