友情支持

如果您觉得这个笔记对您有所帮助,看在D瓜哥码这么多字的辛苦上,请友情支持一下,D瓜哥感激不尽,😜

支付宝

微信

有些打赏的朋友希望可以加个好友,欢迎关注D 瓜哥的微信公众号,这样就可以通过公众号的回复直接给我发信息。

wx jikerizhi

公众号的微信号是: jikerizhi因为众所周知的原因,有时图片加载不出来。 如果图片加载不出来可以直接通过搜索微信号来查找我的公众号。

9. 职责链模式

9.1. 定义

根据 GoF 的著名著作 《设计模式》,职责链模式的定义如下:

职责链模式(Chain of Responsibility)

使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理为止。

— Erich Gamma、Richard Helm、Ralph Johnson、John Vlissides
《设计模式》

9.2. 类图

Diagram

发出这个请求的客户端并不知道这当中的哪一个对象最终处理这个请求,这样系统的更改可以在不影响客户端的情况下动态地重新组织和分配责任。

Handler类,定义一个处理请示的接口。

ConcreteHandler类,具体处理者类,处理它所负责的请求,可访问它的后继者,如果可处理该请求,就处理之,否则就将该请求转发给它的后继者。

最关键的是当客户提交一个请求时,请求是沿链传递直至有一个ConcreteHandler对象负责处理它。[DP]

这就使得接收者和发送者都没有对方的明确信息,且链中的对象自己也并不知道链的结构。结果是职责链可简化对象的相互连接,它们仅需保持一个指向其后继者的引用,而不需保持它所有的候选接受者的引用[DP]。这也就大大降低了耦合度了。

由于是在客户端来定义链的结构,也就是说,我可以随时地增加或修改处理一个请求的结构。增强了给对象指派职责的灵活性[DP]。

一个请求极有可能到了链的末端都得不到处理,或者因为没有正确配置而得不到处理,这就很糟糕了。需要事先考虑全面。

代码 62. chainofresponsibility/Client.java 类
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.diguage.didp.chainofresponsibility;

import java.util.Arrays;

/**
 * Client 类
 *
 * @author D瓜哥, https://www.diguage.com/
 * @since 2017-05-19 17:53:33
 */
public class Client {
  public static void main(String[] args) {
    Handler h1 = new ConcreteHandler1();
    Handler h2 = new ConcreteHandler2();
    Handler h3 = new ConcreteHandler3();
    h1.setSuccessor(h2);
    h2.setSuccessor(h3);

    int[] requests = new int[]{1, 2, 3, 5, 8, 13, 21};
    Arrays.stream(requests).forEach(h1::handleRequest);
  }
}
代码 63. chainofresponsibility/ConcreteHandler1.java 类
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
package com.diguage.didp.chainofresponsibility;

/**
 * ConcreteHandler1 类
 *
 * @author D瓜哥, https://www.diguage.com/
 * @since 2017-05-19 17:53:33
 */
public class ConcreteHandler1 extends Handler {
  @Override
  public void handleRequest(int request) {
    if (request > 0 && request < 10) {
      System.out.printf("%s 处理 %s%n", this.getClass().getName(), request);
    } else if (successor != null) {
      successor.handleRequest(request);
    }
  }
}
代码 64. chainofresponsibility/ConcreteHandler2.java 类
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
package com.diguage.didp.chainofresponsibility;

/**
 * ConcreteHandler2 类
 *
 * @author D瓜哥, https://www.diguage.com/
 * @since 2017-05-19 17:53:33
 */
public class ConcreteHandler2 extends Handler {
  @Override
  public void handleRequest(int request) {
    if (request >= 10 && request < 20) {
      System.out.printf("%s 处理 %s%n", this.getClass().getName(), request);
    } else if (successor != null) {
      successor.handleRequest(request);
    }
  }
}
代码 65. chainofresponsibility/Handler.java 类
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
package com.diguage.didp.chainofresponsibility;

/**
 * Handler 类
 *
 * @author D瓜哥, https://www.diguage.com/
 * @since 2017-05-19 17:53:33
 */
public abstract class Handler {
  protected Handler successor;

  public void setSuccessor(Handler successor) {
    this.successor = successor;
  }

  public abstract void handleRequest(int request);
}
代码 66. chainofresponsibility/ConcreteHandler3.java 类
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
package com.diguage.didp.chainofresponsibility;

/**
 * ConcreteHandler2 类
 *
 * @author D瓜哥, https://www.diguage.com/
 * @since 2017-05-19 17:53:33
 */
public class ConcreteHandler3 extends Handler {
  @Override
  public void handleRequest(int request) {
    if (request >= 20 && request < 30) {
      System.out.printf("%s 处理 %s%n", this.getClass().getName(), request);
    } else if (successor != null) {
      successor.handleRequest(request);
    }
  }
}

9.3. 常见示例

  1. java.util.logging.Logger.log(*)

  2. jakarta.servlet.Filter