参考于 :
大话设计模式
马士兵设计模式视频
代码参考于马士兵设计模式视频
写在开头:职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系
图来自大话设计模式,下面我的代码中,Clien是t依赖于Handler1和Handler2的,不过可以使用配置文件或者直接给Filter集合初始化来解决这种依赖。

1.场景
在网上评论一句话,往往会经过一系列的处理,有没有敏感词之类,现在我们来模拟一下。
把<html>,o.o,和谐
换成 [html],^v^,/*河蟹*/
2.不使用职责链模式
- package com.dingyu.ChainOfResponsibility;
- /**
- * 重点在于模式,故逻辑暂时不考虑
- *
- * @author dingyu
- *
- */
- public class Client01 {
- public static void main(String[] args) {
- String s = "<html>,o.o,和谐";
- s = s.replace("<", "[").replace(">", "]").replace("和谐", "/*河蟹*/").replace("o.o", "^v^");
- System.out.println(s);
- }
- }
缺点:过滤无法复用,无法记录过滤顺序。
3.使用职责链模式
- package com.dingyu.ChainOfResponsibility;
- /**
- * 过滤器,doFilter处理msg字符串
- * @author dingyu
- *
- */
- public interface Filter {
- public String doFilter(String msg);
- }
- package com.dingyu.ChainOfResponsibility;
- /**
- * 处理html符号
- * 测试用的,逻辑不是很严谨
- * @author dingyu
- *
- */
- public class HTMLFilter implements Filter {
- @Override
- public String doFilter(String msg) {
- return msg.replace("<", "[").replace(">", "]");
- }
- }
- package com.dingyu.ChainOfResponsibility;
- /**
- * 过滤敏感词汇
- * @author dingyu
- *
- */
- public class SensitiveWordFilter implements Filter {
- @Override
- public String doFilter(String msg) {
- return msg.replace("和谐", "/*河蟹*/");
- }
- }
- package com.dingyu.ChainOfResponsibility;
- /**
- * 处理符号
- * @author dingyu
- *
- */
- public class SymbolFilter implements Filter {
- @Override
- public String doFilter(String msg) {
- return msg.replace("o.o", "^v^");
- }
- }
- package com.dingyu.ChainOfResponsibility;
- import java.util.ArrayList;
- import java.util.List;
- public class Client {
- private static List<Filter> filters = new ArrayList<Filter>();
- private static int index = 0;
- public static void main(String[] args) {
- String s = "<html>,o.o,和谐";
- filters.add(new HTMLFilter());
- filters.add(new SymbolFilter());
- filters.add(new SensitiveWordFilter());
- for (Filter filter : filters) {
- s = filter.doFilter(s);
- }
- System.out.println(s);
- }
- }
虽然使用职责链模式,但仍然有缺点,上面的顺序是先HTML,然后Symbol,最后SensitiveWord,这三个构成一个过滤链条,如果有一天我需要把另一个过滤链条插入到这根链条中间,实现起来很麻烦。
4.改进职责链模式
- package com.dingyu.ChainOfResponsibility;
- import java.util.ArrayList;
- import java.util.List;
- /**
- *
- * @author dingyu
- *
- */
- public class FilterChain implements Filter {
- private List<Filter> filters = new ArrayList<Filter>();
- public void add(Filter filter) {
- filters.add(filter);
- }
- public List<Filter> getFilters() {
- return filters;
- }
- @Override
- public String doFilter(String msg) {
- for (Filter filter : filters) {
- msg = filter.doFilter(msg);
- }
- return msg;
- }
- }
- package com.dingyu.ChainOfResponsibility;
- import java.util.ArrayList;
- import java.util.List;
- public class Client {
- // private static List<Filter> filters = new ArrayList<Filter>();
-
- public static void main(String[] args) {
- String s = "<html>,o.o,和谐";
- // 链条1
- FilterChain chain1 = new FilterChain();
- chain1.add(new HTMLFilter());
- // 链条2
- FilterChain chain2 = new FilterChain();
- chain2.add(new HTMLFilter());
- chain2.add(new SensitiveWordFilter());
- // 链条2插到链条1后
- chain1.add(chain2);
- chain1.add(new SymbolFilter());
- s = chain1.doFilter(s);
- System.out.println(s);
- // filters.add(new HTMLFilter());
- // filters.add(new SymbolFilter());
- // filters.add(new SensitiveWordFilter());
- // for (Filter filter : filters) {
- // s = filter.doFilter(s);
- // }
- // System.out.println(s);
- }
- }
建议debug , eclipse快捷键

5. 职责链实现双向过滤
思路类似于递归,建议使用debug一步步调试。

- package com.dingyu.ChainOfResponsibility;
- /**
- * 过滤器,doFilter处理msg字符串
- *
- * @author dingyu
- *
- */
- public interface Filter {
- // public String doFilter(String msg);
- public void doFilter(Request request, Reponse reponse, FilterChain filterChain);
- }
- package com.dingyu.ChainOfResponsibility;
- /**
- * 处理html符号 测试用的,逻辑不是很严谨
- *
- * @author dingyu
- *
- */
- public class HTMLFilter implements Filter {
- @Override
- public void doFilter(Request request, Reponse reponse, FilterChain filterChain) {
- request.getRequestMsg().replace("<", "[").replace(">", "]");
- filterChain.doFilter(request, reponse, filterChain);
- reponse.setReponseMsg(reponse.getReponseMsg() + "-----HTMLFilter");
- }
- // @Override
- // public String doFilter(String msg) {
- // return msg.replace("<", "[").replace(">", "]");
- // }
- }
- package com.dingyu.ChainOfResponsibility;
- /**
- * 过滤敏感词汇
- *
- * @author dingyu
- *
- */
- public class SensitiveWordFilter implements Filter {
- @Override
- public void doFilter(Request request, Reponse reponse, FilterChain filterChain) {
- request.getRequestMsg().replace("和谐", "/*河蟹*/");
- filterChain.doFilter(request, reponse, filterChain);
- reponse.setReponseMsg(reponse.getReponseMsg() + "-----SensitiveWordFilter");
- }
- // @Override
- // public String doFilter(String msg) {
- // return msg.replace("和谐", "/*河蟹*/");
- // }
- }
- package com.dingyu.ChainOfResponsibility;
- /**
- * 处理符号
- *
- * @author dingyu
- *
- */
- public class SymbolFilter implements Filter {
- @Override
- public void doFilter(Request request, Reponse reponse, FilterChain filterChain) {
- request.getRequestMsg().replace("o.o", "^v^");
- filterChain.doFilter(request, reponse, filterChain);
- reponse.setReponseMsg(reponse.getReponseMsg() + "-----SymbolFilter");
- }
- // @Override
- // public String doFilter(String msg) {
- // return msg.replace("o.o", "^v^");
- // }
- }
- package com.dingyu.ChainOfResponsibility;
- import java.util.ArrayList;
- import java.util.List;
- /**
- *
- * @author dingyu
- *
- */
- public class FilterChain implements Filter {
- private List<Filter> filters = new ArrayList<Filter>();
- private int index=-1;
- public void add(Filter filter) {
- filters.add(filter);
- }
- public List<Filter> getFilters() {
- return filters;
- }
- // @Override
- // public String doFilter(String msg) {
- // for (Filter filter : filters) {
- // msg = filter.doFilter(msg);
- // }
- // return msg;
- // }
- @Override
- public void doFilter(Request request, Reponse reponse, FilterChain filterChain) {
- if (index == filters.size()-1)
- return;
- index++;
- filters.get(index).doFilter(request, reponse, filterChain);
-
- }
- }
- package com.dingyu.ChainOfResponsibility;
- public class Client03 {
- public static void main(String[] args) {
- Request request = new Request();
- Reponse reponse = new Reponse();
- request.setRequestMsg("<html>,o.o,和谐");
- reponse.setReponseMsg("hahahahaha");
- FilterChain chain = new FilterChain();
- chain.add(new HTMLFilter());
- chain.add(new SensitiveWordFilter());
- chain.add(new SymbolFilter());
- chain.doFilter(request, reponse, chain);
- System.out.println(request.getRequestMsg());
- System.out.println(reponse.getReponseMsg());
- }
- }