設計模式之——責任鏈模式

苹果V發表於2024-06-24

責任鏈模式(Chain of Responsibility)是一種行為型設計模式,它將請求的傳送者和接收者解耦,形成一個處理請求的鏈條。每個接收者都有機會處理請求,直到請求被處理完成或者到達鏈條的末尾。

責任鏈模式主要解決的問題是將請求的傳送者和接收者解耦,避免請求傳送者與接收者之間的緊耦合關係。它可以使多個物件都有機會處理請求,從而靈活地組織和處理複雜的業務邏輯。

需要使用責任鏈模式的時候,通常有以下情況:

  1. 當有多個物件可以處理同一個請求時,並且具體由哪個物件處理請求在執行時決定。
  2. 當希望動態地組合和切換物件處理請求時,可以透過改變鏈條的順序或者增加/移除鏈條中的處理者來實現。

假設你是一個團隊的經理,你的團隊需要向公司申請一筆經費。按照責任鏈模式,你首先會審查申請,如果金額超過你的審批許可權,你會將申請轉交給更高層級的領導,直到找到合適的領導來批准申請。在這個過程中,每個領導都有機會審批申請,直到申請被批准或者到達最高層級的領導。

責任鏈模式的優點包括:

  1. 解耦傳送者和接收者:傳送者不需要知道誰將會處理請求,而接收者也不需要知道請求的傳送者是誰,從而實現解耦。
  2. 靈活性和可擴充套件性:可以動態地組合和切換處理者的順序,增加或刪除處理者,從而靈活地處理不同的請求。
  3. 可維護性:每個處理者只關注自己的責任範圍,使得程式碼更加清晰、可讀、可維護。

責任鏈模式也有一些缺點:

  1. 請求可能無法被處理:如果沒有合適的處理者來處理請求,請求可能會到達鏈條的末尾而無法得到處理。
  2. 效能影響:由於請求需要在整個鏈條上傳遞,可能會對效能產生一定的影響。

適合使用責任鏈模式的場景包括:

  1. 當有多個物件可以處理同一請求,且具體由哪個物件處理在執行時確定時,可以使用責任鏈模式。
  2. 當希望動態地組合和切換物件來處理請求時,可以使用責任鏈模式。

下面是一個簡單的程式碼示例,展示了責任鏈模式的使用:

// Request 類表示請求
class Request {
    private String content;
    private int amount;

    public Request(String content, int amount) {
        this.content = content;
        this.amount = amount;
    }

    public String getContent() {
        return content;
    }

    public int getAmount() {
        return amount;
    }
}

// Handler 抽象類表示處理者
abstract class Handler {
    protected Handler successor;

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

    public abstract void handleRequest(Request request);
}

// Manager 類表示經理
class Manager extends Handler {
    private int approvalLimit;

    public Manager(int approvalLimit) {
        this.approvalLimit = approvalLimit;
    }

    @Override
    public void handleRequest(Request request) {
        if (request.getAmount() <= approvalLimit) {
            System.out.println("Manager approves the request: " + request.getContent());
        } else if (successor != null) {
            successor.handleRequest(request);
        }
    }
}

// Director 類表示主管
class Director extends Handler {
    private int approvalLimit;

   public Director(int approvalLimit) {
        this.approvalLimit = approvalLimit;
    }

    @Override
    public void handleRequest(Request request) {
        if (request.getAmount() <= approvalLimit) {
            System.out.println("Director approves the request: " + request.getContent());
        } else if (successor != null) {
            successor.handleRequest(request);
        }
    }
}

// CEO 類表示執行長
class CEO extends Handler {
    @Override
    public void handleRequest(Request request) {
        System.out.println("CEO approves the request: " + request.getContent());
    }
}

// 客戶端程式碼
public class Client {
    public static void main(String[] args) {
        Handler manager = new Manager(1000);
        Handler director = new Director(5000);
        Handler ceo = new CEO();

        manager.setSuccessor(director);
        director.setSuccessor(ceo);

        Request request1 = new Request("Expense reimbursement", 800);
        Request request2 = new Request("Project budget", 3000);
        Request request3 = new Request("New hire request", 10000);

        manager.handleRequest(request1);
        manager.handleRequest(request2);
        manager.handleRequest(request3);
    }
}

在上面的示例中,我們使用責任鏈模式來處理不同的請求。

每個處理者(Manager、Director、CEO)都有一個審批限額,當請求的金額小於等於審批限額時,當前處理者可以處理請求;

否則,請求會傳遞給下一個處理者。

最終,請求會被合適的處理者處理或者到達鏈條的末尾。

透過使用責任鏈模式,我們可以靈活地組合和切換處理者的順序,同時解耦了請求的傳送者和接收者。

這樣,我們可以動態地調整責任鏈,實現不同的處理邏輯,提高程式碼的靈活性和可維護性。

需要注意的是,責任鏈模式並不是要求所有請求都能被處理,而是將請求的處理分散到不同的處理者中,以提高靈活性和可擴充套件性。

相關文章