美文网首页
责任链模式

责任链模式

作者: 狐尼克朱迪 | 来源:发表于2016-10-23 12:05 被阅读0次

    定义

    当你想要让一个以上的对象有机会能够处理某个请求的时候,就是用责任链模式。

    使用场景

    • 有多个对象要处理请求,并且处理程序事先是不知道的。 处理程序在运行时决定是不是处理请求。
    • 你要向几个对象的其中一个发出请求,但不明确地指出是哪个对象处理请求
    • 应该动态地指定可以处理请求的对象集合

    例子

    兽族部落里的国王(King)负责发号施令,指挥官(Commander)负责保卫城堡,官员(officer)负责审判罪犯,士兵(solider)负责收税。
    命令对象是这样的:

    public class Request {
      private final RequestType requestType;
    
      private boolean handled;
    
      public Request(final RequestType requestType, final String requestDescription) {
        this.requestType = Objects.requireNonNull(requestType);
        this.requestDescription = Objects.requireNonNull(requestDescription);
      }
      public void markHandled() {
        this.handled = true;
      }
    }
    

    三种角色分别处理自己对应的国王命令:

    public abstract class RequestHandler {
      private RequestHandler next;
      public RequestHandler(RequestHandler next) {
        this.next = next;
      }
      public void handleRequest(Request req) {
        if (next != null) {
          next.handleRequest(req);
        }
      }
      protected void printHandling(Request req) {
        System.out.println(this + " handling request \"" + req + "\"");
      }
    }
    
    // 指挥官 负责保卫城堡(DEFEND_CASTLE)
    public class OrcCommander extends RequestHandler {
      public OrcCommander(RequestHandler handler) {
        super(handler);
      }
    
      public void handleRequest(Request req) {
        if (req.getRequestType().equals(RequestType.DEFEND_CASTLE)) {
          printHandling(req);
          req.markHandled();
        } else {
          super.handleRequest(req);
        }
      }
    }
    
    // 官员 负责审判犯人(TORTURE_PRISONER)
    public class OrcOfficer extends RequestHandler {
      public OrcOfficer(RequestHandler handler) {
        super(handler);
      }
    
      public void handleRequest(Request req) {
        if (req.getRequestType().equals(RequestType.TORTURE_PRISONER)) {
          printHandling(req);
          req.markHandled();
        } else {
          super.handleRequest(req);
        }
      }
    }
    
    // 士兵 负责收税(COLLECT_TAX)
    public class OrcSoldier extends RequestHandler {
      public OrcSoldier(RequestHandler handler) {
        super(handler);
      }
    
      public void handleRequest(Request req) {
        if (req.getRequestType().equals(RequestType.COLLECT_TAX)) {
          printHandling(req);
          req.markHandled();
        } else {
          super.handleRequest(req);
        }
      }
    }
    

    国王构建一个职责链,请求会经过这个链条进行请求处理:

    // 国王 发号施令。  命令会经过一个有指挥官、官员、士兵组成的职责链处理
    public class OrcKing {
      RequestHandler chain;
    
      public OrcKing() {
        buildChain();
      }
      // 构建职责链
      private void buildChain() { 
        chain = new OrcCommander(new OrcOfficer(new OrcSoldier(null)));
      }
      public void makeRequest(Request req) {
        chain.handleRequest(req);
      }
    }
    

    发个命令试试:

    // 搞个命令
    public class App {
      public static void main(String[] args) {
        OrcKing king = new OrcKing();
        king.makeRequest(new Request(RequestType.DEFEND_CASTLE, "defend castle"));
        king.makeRequest(new Request(RequestType.TORTURE_PRISONER, "torture prisoner"));
        king.makeRequest(new Request(RequestType.COLLECT_TAX, "collect tax"));
      }
    }
    

    分析

    职责链的优点:

    • 将请求的发送者和接受者解耦
    • 简化对象,因为它不需要知道链的结构
    • 通过改变链内的成员或调动它们的次序,允许你动态地新增或删除责任

    职责链的用途和缺点:

    • 窗口系统中处理鼠标和键盘事件
    • 并不保证请求一定被执行
    • 可能不太容易观察运行时的特征,有碍于除错

    参考

    iluwatar/java-design-patterns

    相关文章

      网友评论

          本文标题:责任链模式

          本文链接:https://www.haomeiwen.com/subject/oefkuttx.html