责任链模式- 2020-12-01 23:05- 设计模式: 责任链模式,设计模式


概念

责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。
在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。

模拟ServeltFitler实现责任链

模拟请求对象 ServletRequest

  1. /**
  2. * 模拟请求对象 ServletRequest
  3. *
  4. * @author Bai
  5. * @date 2020/12/1 21:34
  6. */
  7. @Data
  8. public class Request {
  9. /**
  10. * 请求消息
  11. */
  12. private String msg;
  13. /**
  14. * 上下文
  15. */
  16. private String text;
  17. }

模拟响应对象ServletResponse

  1. /**
  2. * 响应
  3. *
  4. * @author Bai
  5. * @date 2020/12/1 21:34
  6. */
  7. @Data
  8. public class Response {
  9. /**
  10. * 响应消息
  11. */
  12. private String msg;
  13. /**
  14. * 上下文
  15. */
  16. private String text;
  17. }

模拟Filter对象:javax.servlet.Filter

  1. /** 请求过滤器
  2. * @author Bai
  3. * @date 2020/12/1 21:33
  4. */
  5. public interface Filter {
  6. /**
  7. * @param request 请求
  8. * @param response 响应
  9. * @param filterChain 责任链
  10. * @return
  11. */
  12. boolean doFilter(Request request, Response response, FilterChain filterChain);
  13. }

自定义Filter

  1. /**
  2. * 替换指定文本
  3. *
  4. * @author Bai
  5. * @date 2020/12/1 21:44
  6. */
  7. public class TextFilter implements Filter {
  8. @Override
  9. public boolean doFilter(Request request, Response response, FilterChain filterChain) {
  10. request.setText(request.getText() + "TextFilter() ");
  11. //请求主要逻辑处理
  12. request.setMsg(request.getMsg().replace("加班", "休息"));
  13. request.setMsg(request.getMsg().replace("破解", "使用"));
  14. //调用下一个节点
  15. filterChain.doFilter(request, response, filterChain);
  16. //处理响应
  17. response.setText(response.getText() + "TextFilter() ");
  18. return true;
  19. }
  20. }

  1. /**
  2. * 非法字符替换
  3. *
  4. * @author Bai
  5. * @date 2020/12/1 21:53
  6. */
  7. public class IllegalSymbolFilter implements Filter {
  8. @Override
  9. public boolean doFilter(Request request, Response response, FilterChain filterChain) {
  10. request.setText(request.getText() + "IllegalSymbolFilter() ");
  11. //请求主要逻辑处理
  12. request.setMsg(request.getMsg().replace("<", "{"));
  13. request.setMsg(request.getMsg().replace(">", "}"));
  14. //调用下一个节点
  15. filterChain.doFilter(request, response, filterChain);
  16. //处理响应
  17. response.setText(response.getText() + "IllegalSymbolFilter() ");
  18. return true;
  19. }
  20. }

模拟责任链 javax.servlet.FilterConfig

  1. /**
  2. * 责任链
  3. * 实现 Filter 意味着本身也可以作为责任链中的一个节点 加入另外一个责任链
  4. *
  5. * @author Bai
  6. * @date 2020/12/1 21:36
  7. */
  8. public class FilterChain implements Filter {
  9. /**
  10. * 集合下标,每执行一次节点+1
  11. */
  12. private int index = 0;
  13. /**
  14. * 存放每个节点的 filter
  15. */
  16. private List<Filter> FILTER_LIST = new ArrayList<>();
  17. /**
  18. * 向集合中添加节点
  19. *
  20. * @param filter
  21. * @return 可以使用连式编程
  22. */
  23. public FilterChain add(Filter filter) {
  24. FILTER_LIST.add(filter);
  25. return this;
  26. }
  27. @Override
  28. public boolean doFilter(Request request, Response response, FilterChain filterChain) {
  29. //执行到最后一个节点后 不再执行
  30. if (index >= FILTER_LIST.size()) {
  31. return false;
  32. }
  33. //每次只执行指定的节点
  34. Filter filter = FILTER_LIST.get(index++);
  35. //每执行一个节点+1
  36. return filter.doFilter(request, response, filterChain);
  37. }
  38. }

模拟一次请求

  1. @Test
  2. public void dome() {
  3. //模拟一次请求
  4. Request request = new Request();
  5. request.setMsg("<javaScript>hello,我是黑客,我在加班,破解你们的系统");
  6. request.setText("start -> ");
  7. //响应
  8. Response response = new Response();
  9. response.setMsg("end -> ");
  10. //生成责任链
  11. FilterChain chain = new FilterChain();
  12. //添加节点
  13. chain.add(new TextFilter());
  14. chain.add(new IllegalSymbolFilter());
  15. chain.doFilter(request, response, chain);
  16. System.out.println(request.getMsg());
  17. System.out.println(request.getText());
  18. System.out.println(response.getText());
  19. }
  1. {javaScript}hello,我是黑客,我在休息,使用你们的系统
  2. start -> TextFilter() IllegalSymbolFilter()
  3. nullIllegalSymbolFilter() TextFilter()

将责任链作为节点

  1. /**
  2. * 责任链做为另外一个责任链的节点
  3. */
  4. @Test
  5. public void dome2() {
  6. //模拟一次请求
  7. Request request = new Request();
  8. request.setMsg("<javaScript>hello,我是黑客,我在加班,破解你们的系统");
  9. request.setText("start -> ");
  10. //响应
  11. Response response = new Response();
  12. response.setMsg("end -> ");
  13. //生成责任链
  14. FilterChain chain = new FilterChain();
  15. chain.add(new TextFilter());
  16. FilterChain chain2 = new FilterChain();
  17. //将责任链作为另外一个链路的节点
  18. chain2.add(new IllegalSymbolFilter());
  19. chain.add(chain2);
  20. chain.doFilter(request, response, chain);
  21. System.out.println(request.getMsg());
  22. System.out.println(request.getText());
  23. System.out.println(response.getText());
  24. }

**