1. 定义

为请求创建了一个接收者对象的链。

2. 案例

image.png
来一个请求,需要经过很多步处理,每一步处理成功后才能进行下一步,所有实现都放process中也可实现,但是不利于扩展维护:

Request:用建造者模式模拟请求频率、登录验证、访问权限、敏感词是否成功

  1. class Request {
  2. private boolean loggedOn;//是否登录
  3. private boolean frequentOk;//是否请求频繁
  4. private boolean isPermits;//是否有访问权限
  5. private boolean containsSensitiveWords;//是否有敏感词
  6. public Request(boolean loggedOn, boolean frequentOk, boolean isPermits, boolean containsSensitiveWords) {
  7. this.loggedOn = loggedOn;
  8. this.frequentOk = frequentOk;
  9. this.isPermits = isPermits;
  10. this.containsSensitiveWords = containsSensitiveWords;
  11. }
  12. public boolean isLoggedOn() {
  13. return loggedOn;
  14. }
  15. public boolean isFrequentOk() {
  16. return frequentOk;
  17. }
  18. public boolean isPermits() {
  19. return isPermits;
  20. }
  21. public boolean isContainsSensitiveWords() {
  22. return containsSensitiveWords;
  23. }
  24. //构造器:静态内部类
  25. static class RequestBuilder {
  26. private boolean loggedOn;
  27. private boolean frequentOk;
  28. private boolean isPermits;
  29. private boolean containsSensitiveWords;
  30. RequestBuilder loggedOn(boolean loggedOn) {
  31. this.loggedOn = loggedOn;
  32. return this;
  33. }
  34. RequestBuilder frequentOk(boolean frequentOk) {
  35. this.frequentOk = frequentOk;
  36. return this;
  37. }
  38. RequestBuilder isPermits(boolean isPermits) {
  39. this.isPermits = isPermits;
  40. return this;
  41. }
  42. RequestBuilder containsSensitiveWords(boolean containsSensitiveWords) {
  43. this.containsSensitiveWords = containsSensitiveWords;
  44. return this;
  45. }
  46. public Request build() {
  47. Request request = new Request(loggedOn, frequentOk, isPermits, containsSensitiveWords);
  48. return request;
  49. }
  50. }
  51. }

定义处理器链表:

  1. //定义链表
  2. abstract class Handler {
  3. Handler next;
  4. public Handler(Handler next) {
  5. this.next = next;
  6. }
  7. public Handler getNext() {
  8. return next;
  9. }
  10. public void setNext(Handler next) {
  11. this.next = next;
  12. }
  13. //处理每个节点
  14. abstract boolean process(Request request);
  15. }

请求频率处理

  1. // 请求频率处理
  2. class FrequentHandler extends Handler {
  3. public FrequentHandler(Handler next) {
  4. super(next);
  5. }
  6. @Override
  7. boolean process(Request request) {
  8. System.out.println("访问频率控制.");
  9. if (request.isFrequentOk()) {
  10. Handler next = getNext();
  11. if (next == null) {
  12. return true;
  13. }
  14. //处理下个节点
  15. if (!next.process(request)) {//下个节点处理失败,返回false
  16. return false;
  17. } else {
  18. return true;
  19. }
  20. }
  21. return false;
  22. }
  23. }

登录处理

  1. //登录处理
  2. class LoggingHandler extends Handler {
  3. public LoggingHandler(Handler next) {
  4. super(next);
  5. }
  6. @Override
  7. boolean process(Request request) {
  8. System.out.println("登录验证.");
  9. if (request.isLoggedOn()) {
  10. Handler next = getNext();
  11. if (next == null) {
  12. return true;
  13. }
  14. //处理下个节点
  15. if (!next.process(request)) {//下个节点处理失败,返回false
  16. return false;
  17. } else {
  18. return true;
  19. }
  20. }
  21. return false;
  22. }
  23. }

权限、敏感词handler省略….

使用:

  1. public static void main(String[] args) {
  2. Request request = new Request.RequestBuilder().frequentOk(true).loggedOn(true).build();
  3. FrequentHandler handler = new FrequentHandler(new LoggingHandler(null));
  4. if (handler.process(request)) {
  5. System.out.println("正常业务处理");
  6. } else {
  7. System.out.println("访问异常");
  8. }
  9. //------输出--------
  10. //访问频率控制.
  11. //登录验证.
  12. //正常业务处理
  13. Request request2 = new Request.RequestBuilder().frequentOk(false).loggedOn(true).build();
  14. FrequentHandler handler2 = new FrequentHandler(new LoggingHandler(null));
  15. if (handler.process(request2)) {
  16. System.out.println("正常业务处理");
  17. } else {
  18. System.out.println("访问异常");
  19. }
  20. //------输出--------
  21. //访问频率控制.
  22. //访问异常
  23. }

3. 应用场景:

一个请求的处理需要多个对象当中的一个或几个协作处理。

4. 优点:

  1. 请求的发送者和接受者解耦
  2. 可以控制执行顺序
  3. 符合开闭原则和单一职责原则

    5. 源码应用

    1. javax.servlet.Filter
    2. javax.servlet.FilterChain