#责任链(ChainOfResponsibility)java
对于设计模式的学习,必定要动手,并且要屡次练习,而后慢慢消化和理解,才能明白其精髓。可是,设计模式只是在特殊情景下的特殊解决方案,不要滥用,不要为了使用设计模式而硬生生得去使用。设计模式的使用应该天然、优雅!web
public class TestMain { public static void main(String[] args) { String str = "你好:),这句话中有敏感词汇,须要处理。<script>,敏感!"; MsgProcessor pro = new MsgProcessor(); pro.setMsg(str); str = pro.processor();--- System.out.println(str); } }
另外一个类:编程
public class MsgProcessor { private String msg; public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public String processor(){ String content = ""; if(null != msg && !("").equals(msg.trim())){ content = msg.replace("<", "{") .replace(">", "}"); content = content.replace("敏感", ""); content = content.replace(":)", "^V^"); } return content; } }
上面的代码完成了对一个字符串的简单过滤,可是很明显这样的代码很很差。扩展性很差,写得也不够好。这样之后须要添加别的过滤功能不是很方便,老是要修改这个类,一点都不灵活,想把对字符串的过滤行为抽象出来,由于这部分是变化的,天然而然想到使用接口。设计模式
代码修改成:数组
public String processor(){ if(null != msg && !("").equals(msg.trim())){ msg = new HTMLFilter().doFilter(msg); msg = new SmileFilter().doFilter(msg); msg = new SensitivityFilter().doFilter(msg); } return msg; }
这样仍是不够灵活,直接在 ** MsgProcessor ** 类中添加一个数组来保存过滤器,而后在 ** processor** 方法中进行屡次调用:数据结构
修改成:ide
public String processor(){ if(null != msg && !("").equals(msg.trim())){ for(Filter f : filters){ msg = f.doFilter(msg); } } return msg; }
这样调整后,全部的过滤器都起做用了,添加起来更加灵活一些,而且过滤器的执行顺序也是可控的。学习
当多个过滤器组合在一块儿,就造成了过滤器链,到这里,责任链有点雏形了。this
若是原本已经存在一个过滤器链条了,我想把一些新的过滤器链加进去,而且加入的顺序能够随意控制(随意组合任意的过滤器链条),该怎么办呢?设计
定义一个过滤器链类,这这个类中定义添加过滤器的方法,以及运行整个链条上的全部过滤器的方法,而且返回结果。
代码修改成:
MsgProcessor.java :
public class MsgProcessor { private String msg; private FilterChain fc; public FilterChain getFc() { return fc; } public void setFc(FilterChain fc) { this.fc = fc; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public String processor(){ return fc.doFilter(msg); } }
FilterChain.java:
public class FilterChain { List<Filter> filters = new ArrayList<Filter>(); public FilterChain addFilter(Filter filter){ filters.add(filter); return this; } public String doFilter(String str){ if(null != str && !("").equals(str.trim())){ for(Filter f : filters){ str = f.doFilter(str); } } return str; } }
TestMain.java
public class TestMain { public static void main(String[] args) { String str = "你好:),这句话中有敏感词汇,须要处理。<script>,敏感!"; MsgProcessor mp = new MsgProcessor(); mp.setMsg(str); FilterChain fc = new FilterChain(); fc.addFilter(new HTMLFilter()) .addFilter(new SmileFilter()) .addFilter(new SensitivityFilter()); mp.setFc(fc); str = mp.processor(); System.out.println(str); } }
写到这里,仍是没有解决咱们的问题,怎样灵活合并过滤器链呢? 很简单,咱们能够将过滤器链这个类,看成一个很大的过滤器来处理,这样就能够了。让** FilterChain **也实现Filter接口,这样就解决了这个问题!完成这一步,就已经有了责任链模式的味道了!
在实际开发中,咱们见过的过滤器都能进行双向的处理,也就是说,能处理request和response,并且是先挨着处理request,而后再反向处理response,这又是怎么实现的呢?
定义一个Request和Response,在实际的web容器中,容器会帮助咱们生成这两个对象,并且在其中封装了不少的东西,在这里,只是模拟,只需简单定义就能够了。
Request.java
public class Request { private String requestStr; public String getRequestStr() { return requestStr; } public void setRequestStr(String requestStr) { this.requestStr = requestStr; } }
Response.java
public class Response { private String responseStr; public String getResponseStr() { return responseStr; } public void setResponseStr(String responseStr) { this.responseStr = responseStr; } }
定义好这两个类以后,修改以前的程序:
Filter.java
public interface Filter { public abstract void doFilter(Request request, Response response); }
别的代码跟着这个接口一块儿改就能够了,可是你会发现,仍是不能实现咱们想要的效果,这个时候须要一些编程的手法,咱们继续修改Filter接口:
Filter.java
public interface Filter { public abstract void doFilter(Request request, Response response, FilterChain filterChain); }
为何要这样修改,由于只有这样才能把链条握在每个过滤器手中,有了链条,就能够控制链条了:
FilterChain.java
public class FilterChain implements Filter { private List<Filter> filters = new ArrayList<Filter>(); private int index = 0; public FilterChain addFilter(Filter filter){ this.filters.add(filter); return this; } @Override public void doFilter(Request request, Response response, FilterChain filterChain) { if(index >= filters.size()) return; Filter f = filters.get(index); index++; f.doFilter(request, response, filterChain); } }
HTMLFilter.java
public class HTMLFilter implements Filter { @Override public void doFilter(Request request, Response response, FilterChain filterChain) { String str = request.getRequestStr(); System.out.println(str); filterChain.doFilter(request, response, filterChain); String resStr = response.getResponseStr(); System.out.println(resStr); } }
如今来看,每一个过滤器都持有过滤器链,在处理完request后,调用下一个过滤器,因为方法是栈结构,这样就会造成一个过滤器栈,拥有栈的数据结构特色。这也是为何Struts在配置多个拦截器的时候,成为拦截器栈的缘由。 因为栈的数据特色,就能达到咱们想要的特色,按照过滤器的次序,依次处理完request,而后再反向依次处理response。这就是责任链模式在实际开发中的使用。