責任鏈模式

責任鏈模式

定義

使多個對象都有機會處理請求,從而避免了請求的發送者和接收者致敬的耦合關係。將這些對象連成一條鏈,並沿着這條鏈傳遞該請求,直到有對象處理它爲止。bash

使用場景

  • 多個對象能夠處理同一請求,可是具體有哪一個來處理則在運行時動態決定
  • 在請求處理者不明確的狀況下向多個對象中的一個提交請求
  • 須要動態指定一組對象處理請求
  • 代碼中存在多個if-else語句的狀況下,此時能夠考慮使用責任鏈模式來對代碼進行重構。

結構

  • AbstractHandleride

    抽象處理角色,聲明瞭處理對象處理請求的方法,並在其中保存一個對下一個處理節點AbstractHandler的引用性能

  • AbstractRequest測試

    抽象請求者或者具體請求者,根據不一樣需求能夠選擇性採起策略ui

簡單實現

模擬請假流程this

public abstract class Leader {

  /**
   * 下一節點上的處理者對象
   */
  protected Leader nextHandler;

  /**
   * 處理請求
   *
   * @param request 請求對象
   */
  public final void handlerRequest(LeaveRequest request) {
    if (request.getDay() <= limit()) {
      handle(request);
    } else {
      if (null != nextHandler) {
        nextHandler.handlerRequest(request);
      }
    }
  }

  /**
   * 請求處理
   *
   * @param request 請求條件
   */
  protected abstract void handle(LeaveRequest request);

  /**
   * 有權審批的最大天數
   *
   * @return 最大天數
   */
  public abstract int limit();
}
複製代碼

Leader類充當AbstractHandler的角色,負責主要的邏輯實現;責任轉發的邏輯交由handlerRequest()實現,聲明瞭一個獲取限制條件的limit()抽象方法spa

public class LeaveRequest {

  private String name;
  private int day;

  public LeaveRequest(String name, int day) {
    this.name = name;
    this.day = day;
  }
     //get set 省略
     ...
     
  }
複製代碼

LeaveRequest爲請求者的信息,這裏爲了簡單,沒有使用抽象類code

public class TeamLeader extends Leader {

  private String name;

  public TeamLeader(String name) {
    this.name = name;
  }

  @Override protected void handle(LeaveRequest request) {
    System.out.println(name + "審批員工" + request.getName() + " 的請假條,請假天數爲" + request.getDay() + "天");
  }

  @Override public int limit() {
    return 3;
  }
}
複製代碼
public class Manager extends Leader {

  private String name;

  public Manager(String name) {
    this.name = name;
  }

  @Override protected void handle(LeaveRequest request) {
    System.out.println(name + "審批員工" + request.getName() + " 的請假條,請假天數爲" + request.getDay() + "天");
  }

  @Override public int limit() {
    return 10;
  }
}
複製代碼
public class Director extends Leader {

  private String name;

  public Director(String name) {
    this.name = name;
  }

  @Override protected void handle(LeaveRequest request) {
    System.out.println(name + "審批員工" + request.getName() + " 的請假條,請假天數爲" + request.getDay() + "天");
  }

  @Override public int limit() {
    return 15;
  }
}
複製代碼
public class Boss extends Leader {

  private String name;

  public Boss(String name) {
    this.name = name;
  }

  @Override protected void handle(LeaveRequest request) {
    System.out.println(name + "審批員工 " + request.getName() + " 的請假條,請假天數爲" + request.getDay() + "天");
  }

  @Override public int limit() {
    return Integer.MAX_VALUE;
  }
}
複製代碼

具體的幾個處理者對象,各自負責各自功能的實現對象

public class Test {

  public static void main(String[] args) {

    // 處理者對象
    Leader handler1 = new TeamLeader("沙僧");
    Leader handler2 = new Manager("八戒");
    Leader handler3 = new Director("悟空");
    Leader handler4 = new Boss(" 唐僧");

    //  請求者對象
    LeaveRequest request1 = new LeaveRequest("張三", 2);
    LeaveRequest request2 = new LeaveRequest("李四", 5);
    LeaveRequest request3 = new LeaveRequest("王五", 11);
    LeaveRequest request4 = new LeaveRequest("趙六", 18);
    LeaveRequest request5 = new LeaveRequest("趙六", 30);

    //設置責任節點鏈
    handler1.nextHandler = handler2;
    handler2.nextHandler = handler3;
    handler3.nextHandler = handler4;

    System.out.println("---------request1---------------");
    handler1.handlerRequest(request1);

    System.out.println("----------request2--------------");
    handler1.handlerRequest(request2);

    System.out.println("-----------request3-------------");
    handler1.handlerRequest(request3);

    System.out.println("-----------request4-------------");
    handler1.handlerRequest(request4);

    System.out.println("-----------request5-------------");
    handler1.handlerRequest(request5);

    System.out.println("-----------request1-------------");
    handler3.handlerRequest(request1);

    System.out.println("-----------request4-------------");
    handler3.handlerRequest(request4);
  }
}

複製代碼

測試類及結果get

---------request1---------------
沙僧審批員工張三 的請假條,請假天數爲2天
----------request2--------------
八戒審批員工李四 的請假條,請假天數爲5天
-----------request3-------------
悟空審批員工王五 的請假條,請假天數爲11天
-----------request4-------------
 唐僧審批員工 趙六 的請假條,請假天數爲18天
-----------request5-------------
 唐僧審批員工 趙六 的請假條,請假天數爲30天
-----------request1-------------
悟空審批員工張三 的請假條,請假天數爲2天
-----------request4-------------
 唐僧審批員工 趙六 的請假條,請假天數爲18天
複製代碼

思考

責任鏈模式理解起來比較簡單,核心的思想就是在AbstractHandler中保留一個AbstractHandler的引用來進行處理

責任鏈模式的主要優勢在於能夠下降系統耦合度,簡化對象的相互鏈接,同時加強給對象指派職責的靈活性,增長新的處理類也很方便

對於比較長的責任鏈,請求的處理可能涉及多個對象,對性能可能會有必定影響

不能保證請求必定被接收,下游的請求沒法傳遞給上游處理

相關文章
相關標籤/搜索