行為型設計模式 - 責任鏈模式詳解

農夫三拳有點疼~發表於2020-05-19

基本介紹

責任鏈模式(chain of Responsibilities Pattern)允許你將請求沿著處理者鏈進行傳送,處理者收到請求後,可以對請求進行處理,或者將其傳遞給下一個處理者。

模式結構

Handler(抽象處理者):定義一個處理請求的介面,並且聚合了一個型別為自身的物件(後繼者),子類可以通過設定後繼者,將請求傳遞下去

ConcreteHandler(具體處理者):具體處理者收到請求後,可以自己將請求處理,或者傳給後繼者。

Request(請求):定義一些屬性,表示一個請求

舉例說明

公司採購審批流程:

  • 金額 <= 5000 由組長審批
  • 5000 < 金額 <= 10000 由經理審批
  • 金額 > 10000 由老闆審批

請求,包含 id 和 價格欄位

public class PurchaseRequest {
    private int id;
    private float price;

    public PurchaseRequest(int id, float price) {
        this.id = id;
        this.price = price;
    }

    public int getId() {
        return id;
    }

    public float getPrice() {
        return price;
    }
}

抽象處理者

public abstract class Approver {
    protected String name;
    protected Approver approver;

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

    public void setApprover(Approver approver) {
        this.approver = approver;
    }

    /**
     * 處理請求
     * @param request
     */
    public abstract void processRequest(PurchaseRequest request);
}

具體處理者

public class TeamLeader extends Approver {

    public TeamLeader(String name) {
        super(name);
    }

    @Override
    public void processRequest(PurchaseRequest request) {
        if (request.getPrice() <= 5000) {
            System.out.println(name + "審批了" + request.getId() + "號請求,價格為" + request.getPrice());
        } else {
            approver.processRequest(request);
        }
    }
}
public class Manager extends Approver {

    public Manager(String name) {
        super(name);
    }

    @Override
    public void processRequest(PurchaseRequest request) {
        if (request.getPrice() > 5000 && request.getPrice() <= 10000) {
            System.out.println(name + "審批了" + request.getId() + "號請求,價格為" + request.getPrice());
        } else {
            approver.processRequest(request);
        }
    }
}
public class Boss extends Approver {

    public Boss(String name) {
        super(name);
    }

    @Override
    public void processRequest(PurchaseRequest request) {
        if (request.getPrice() > 10000) {
            System.out.println(name + "審批了" + request.getId() + "號請求,價格為" + request.getPrice());
        } else {
            approver.processRequest(request);
        }
    }
}

測試類

public class Client {
    @Test
    public void test(){
        PurchaseRequest request = new PurchaseRequest(1, 5000);

        TeamLeader teamLeader = new TeamLeader("李組長");
        Manager manager = new Manager("張經理");
        Boss boss = new Boss("王老闆");

        teamLeader.setApprover(manager);
        manager.setApprover(boss);
        boss.setApprover(teamLeader);

        manager.processRequest(request);
        boss.processRequest(request);
    }
}

執行結果

李組長審批了1號請求,價格為5000.0
李組長審批了1號請求,價格為5000.0

模式分析

優點

  • 降低耦合度。它將請求的傳送者和接收者解耦
  • 簡化了物件。使得物件不需要知道鏈的結構
  • 增強給物件指派職責的靈活性。通過改變鏈內的成員或者調動它們的次序,允許動態地新增或者刪除責任
  • 增加新的請求處理類很方便

缺點

  • 不能保證請求一定被接收
  • 系統效能將受到一定影響,而且在進行程式碼除錯時不太方便,可能會造成迴圈呼叫
  • 可能不容易觀察執行時的特徵,有礙於除錯

適用場景

  • 有多個物件可以處理同一個請求,具體哪個物件處理該請求由執行時刻自動確定
  • 在不明確指定接收者的情況下,向多個物件中的一個提交一個請求
  • 可動態指定一組物件處理請求

相關文章