设计: 模式 标题: 责任链 文件: chain 链接: /patterns/chain/ 分类: 行为 标签:

  • Java
  • 四人帮
  • 困难

目标


通过给多个对象一个处理请求的机会,避免将请求的发送者耦合到它的接收者。将接收对象连接起来,并沿着链传递请求,直到对象处理它为止。

解释


现实世界中的例子

兽人国的国王大声命令他的军队。离国王最接近的分别是指挥官,然后是军官,然后是士兵。这里的指挥官、军官和士兵构成了一个责任链。

简单的说

它有助于建立一连串的对象。 请求从一端进入,并且在链中的对象中传递,直到找到合适的处理逻辑。

维基百科

在面向对象设计中,责任链模式是由命令对象源和一系列处理对象组成的设计模式。 每个处理对象都包含用于定义可处理的命令对象类型的逻辑; 其余的被传递给链中的下一个处理对象。

编程示例


用上面的兽人翻译我们的例子。 首先实现请求类。

  1. public class Request {
  2. private final RequestType requestType;
  3. private final String requestDescription;
  4. private boolean handled;
  5. public Request(final RequestType requestType, final String requestDescription) {
  6. this.requestType = Objects.requireNonNull(requestType);
  7. this.requestDescription = Objects.requireNonNull(requestDescription);
  8. }
  9. public String getRequestDescription() { return requestDescription; }
  10. public RequestType getRequestType() { return requestType; }
  11. public void markHandled() { this.handled = true; }
  12. public boolean isHandled() { return this.handled; }
  13. @Override
  14. public String toString() { return getRequestDescription(); }
  15. }
  16. public enum RequestType {
  17. DEFEND_CASTLE, TORTURE_PRISONER, COLLECT_TAX
  18. }

然后请求处理器层次结构

  1. public abstract class RequestHandler {
  2. private static final Logger LOGGER = LoggerFactory.getLogger(RequestHandler.class);
  3. private RequestHandler next;
  4. public RequestHandler(RequestHandler next) {
  5. this.next = next;
  6. }
  7. public void handleRequest(Request req) {
  8. if (next != null) {
  9. next.handleRequest(req);
  10. }
  11. }
  12. protected void printHandling(Request req) {
  13. LOGGER.info("{} handling request \"{}\"", this, req);
  14. }
  15. @Override
  16. public abstract String toString();
  17. }
  18. public class OrcCommander extends RequestHandler {
  19. public OrcCommander(RequestHandler handler) {
  20. super(handler);
  21. }
  22. @Override
  23. public void handleRequest(Request req) {
  24. if (req.getRequestType().equals(RequestType.DEFEND_CASTLE)) {
  25. printHandling(req);
  26. req.markHandled();
  27. } else {
  28. super.handleRequest(req);
  29. }
  30. }
  31. @Override
  32. public String toString() {
  33. return "Orc commander";
  34. }
  35. }
  36. // OrcOfficer and OrcSoldier are defined similarly as OrcCommander

然后,国王发出命令,并且形成了一条链

  1. public class OrcKing {
  2. RequestHandler chain;
  3. public OrcKing() {
  4. buildChain();
  5. }
  6. private void buildChain() {
  7. chain = new OrcCommander(new OrcOfficer(new OrcSoldier(null)));
  8. }
  9. public void makeRequest(Request req) {
  10. chain.handleRequest(req);
  11. }
  12. }

如下的方式来使用

  1. OrcKing king = new OrcKing();
  2. king.makeRequest(new Request(RequestType.DEFEND_CASTLE, "defend castle")); // Orc commander handling request "defend castle"
  3. king.makeRequest(new Request(RequestType.TORTURE_PRISONER, "torture prisoner")); // Orc officer handling request "torture prisoner"
  4. king.makeRequest(new Request(RequestType.COLLECT_TAX, "collect tax")); // Orc soldier handling request "collect tax"

适用性


如下情况考虑使用责任链设计模式:

  • 多于一个的对象可以处理请求,并且该处理程序不是先验的。 处理程序应该根据参数自动确定。
  • 你想发出一个请求到几个对象中的一个,而不能明确指定接收处理者。
  • 可以动态地指定可以处理请求的对象集合。

真实例子


感谢