设计模式 之 责任链模式
责任链模式是一种对象的行为模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。-- 阎宏博士的《JAVA与模式》
例:模拟过滤器,对请求的数据进行敏感词、中文符号等进行过滤
第一版:通过链式实现Request的请求的处理
过滤器接口
public interface Filter { String doFilter(String msg); }
过滤器链
public class FilterChain { private List<Filter> filters = new ArrayList<Filter>(); public FilterChain addFilter(Filter f) { this.filters.add(f); return this; } public List<Filter> getFilters() { return filters; } }
敏感词过滤器
public class SesitiveFilter implements Filter { @Override public String doFilter(String msg) { String result = msg.replace("黄色", "和谐"); return result; } }
符号过滤器
public class SymbolFilter implements Filter { @Override public String doFilter(String msg) { String result = msg.replace(',', ',').replace('.', '。'); return result; } }
Request消息处理
public class MessageProcessor { private String message; private FilterChain filterChain; public MessageProcessor(String message, FilterChain filterChain) { this.message = message; this.filterChain = filterChain; } public String process() { String result = message; for (Filter f : filterChain.getFilters()) { result = f.doFilter(result); } return result; } }
测试
public class Test { public static void main(String[] args) { String request = "注意,不要将黄色笑话."; FilterChain fc = new FilterChain(); fc.addFilter(new SesitiveFilter()) .addFilter(new SymbolFilter()); MessageProcessor processor = new MessageProcessor(request, fc); String result = processor.process(); System.out.println(result); } }
OK, requst链式处理完成,但仍存在不足:当多个FilterChain时还怎么处理消息?其实FilterChain就是一个大的Filter,所以FilterChain可以实现Filter接口
第二版:修改FilterChain实现Filter接口
public class FilterChain implements Filter { private List<Filter> filters = new ArrayList<Filter>(); public FilterChain addFilter(Filter f) { this.filters.add(f); return this; } @Override public String doFilter(String msg) { String result = msg; for(Filter f : filters) { result = f.doFilter(result); } return result; } }
测试
public class Test { public static void main(String[] args) { String request = "注意,不要讲黄色笑话."; FilterChain fc = new FilterChain(); fc.addFilter(new SesitiveFilter()); FilterChain fc2 = new FilterChain(); fc2.addFilter(new SymbolFilter()); fc.addFilter(fc2); String result = fc.doFilter(request); System.out.println(result); } }
OK,现在可以完美处理request了,但当需要这个FilterChain既能处理客户端发送的信息又可以处理服务器返回的消息就不行了。
第三版:增加对Response的处理
消息封装
// Request public class Request { private String msg; public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } } // Response public class Response { private String msg; public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } }
新Filter
public interface Filter { void doFilter(Request request, Response response); }
敏感字过滤器
public class SesitiveFilter implements Filter { @Override public void doFilter(Request request, Response response) { request.setMsg(request.getMsg().replace("黄色", "和谐")); response.setMsg(response.getMsg().replace("和谐", "黄色")); } }
符号过滤器
public class SymbolFilter implements Filter { @Override public void doFilter(Request request, Response response) { request.setMsg(request.getMsg().replace(',', ',').replace('.', '。')); response.setMsg(response.getMsg().replace(',', ',').replace('。', '.')); } }
过滤链
public class FilterChain implements Filter { private List<Filter> filters = new ArrayList<Filter>(); public FilterChain addFilter(Filter f) { this.filters.add(f); return this; } @Override public void doFilter(Request request, Response response) { for(Filter f : filters) { f.doFilter(request, response); } } }
测试
public class Test { public static void main(String[] args) { Request request = new Request(); request.setMsg("注意,不要讲黄色笑话."); FilterChain fc = new FilterChain(); fc.addFilter(new SesitiveFilter()); FilterChain fc2 = new FilterChain(); fc2.addFilter(new SymbolFilter()); fc.addFilter(fc2); Response response = new Response(); response.setMsg("和谐社会,好。"); fc.doFilter(request, response); System.out.println("Request: " + request.getMsg()); System.out.println("Response: " + response.getMsg()); } }
OK,终于既能处理Reqeust又能处理Response了,But! 好像处理Response时顺序反了
第四版:修正Response的处理顺序
修改Filter
public interface Filter { void doFilter(Request request, Response response, FilterChain chain); }
敏感字过滤器
public class SesitiveFilter implements Filter { @Override public void doFilter(Request request, Response response, FilterChain chain) { request.setMsg(request.getMsg().replace("黄色", "和谐") + "->SesitiveFilter"); chain.doFilter(request, response, chain); response.setMsg(response.getMsg().replace("和谐", "黄色") + "->SesitiveFilter"); } }
符号过滤器
public class SymbolFilter implements Filter { @Override public void doFilter(Request request, Response response, FilterChain chain) { request.setMsg(request.getMsg().replace(',', ',').replace('.', '。') + "->SymbolFilter"); chain.doFilter(request, response, chain); response.setMsg(response.getMsg().replace(',', ',').replace('。', '.') + "->SymbolFilter"); } }
过滤链
public class FilterChain implements Filter { private List<Filter> filters = new ArrayList<Filter>(); private int index = 0; // 记录执行的Filter的顺序 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); } }
测试
public class Test { public static void main(String[] args) { Request request = new Request(); request.setMsg("注意,不要讲黄色笑话."); FilterChain fc = new FilterChain(); fc.addFilter(new SesitiveFilter()); FilterChain fc2 = new FilterChain(); fc2.addFilter(new SymbolFilter()); fc.addFilter(fc2); Response response = new Response(); response.setMsg("和谐社会,好。"); fc.doFilter(request, response, fc); System.out.println("Request: " + request.getMsg()); System.out.println("Response: " + response.getMsg()); } }
OK,大功告成!这就是Web中Filter的处理逻辑!