責任鏈模式

📢 本文由 gemini-2.5-flash 翻譯

Chain of Responsibility Pattern 物件行為模式

目的

使多個物件都有機會處理請求,以避免請求的發送者與接收者之間的耦合關係。將這些物件串聯成一條鏈,並沿著這條鏈傳遞該請求,直到有某個物件處理它為止。

結構

責任鏈模式

其中:

  • Handler 定義一個處理請求的介面;(可選) 實作後續鏈
  • ConcreteHandler 處理它所負責的請求;可存取它的後繼者;如果可以處理該請求,就處理它,否則將請求轉發給後繼者
  • Client 向鏈上的具體處理者 (ConcreteHandler) 物件提交請求

適用性

Chain of Responsibility 模式適用於:

  • 有多個物件可以處理一個請求,哪個物件處理該請求會於執行時自動確定
  • 想在不明確指定接收者的情況下,向多個物件中的一個提交一個請求
  • 可處理一個請求的物件集合應被動態指定

範例

學生請假,先找輔導員,輔導員處理不了就轉呈院長,院長處理不了就轉呈校長。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
public class ChainOfResponsibilityPattern {
    public static void main(String[] args) {
        // 實例化物件
        Handler counsellor = new Counsellor();
        Handler president = new President();
        Handler schoolmaster = new Schoolmaster();

        // 設定物件下一級
        counsellor.next = president;
        president.next = schoolmaster;
        schoolmaster.next = null;

        // 向輔導員請求 7 天假期
        counsellor.HandlerRequest(7);
    }
}

abstract class Handler{
    protected Handler next;

    public void setNext(Handler next){
        this.next = next;
    }

    // 學生請假請求
    public abstract void HandlerRequest(int request);
}

class Counsellor extends Handler{
    // 輔導員 審批小於等於 7 天的假
    @Override
    public void HandlerRequest(int request){
        if (request <= 7) {
            System.out.println("Counsellor Agree!");
        }
        else {
            if(next != null){
                next.HandlerRequest(request);
            }
            else {
                System.out.println("Counsellor Refuse!");
            }
        }
    }
}

class President extends Handler{
    // 院長 審批小於等於 15 天的假
    @Override
    public void HandlerRequest(int request){
        if (request <= 15) {
            System.out.println("President Agree!");
        }
        else {
            if(next != null){
                next.HandlerRequest(request);
            }
            else {
                System.out.println("President Refuse!");
            }
        }
    }
}

class Schoolmaster extends Handler{
    // 校長 審批小於等於 30 天的假
    @Override
    public void HandlerRequest(int request){
        if (request <= 30) {
            System.out.println("Schoolmaster Agree!");
        }
        else {
            if(next != null){
                next.HandlerRequest(request);
            }
            else {
                System.out.println("Schoolmaster Refuse!");
            }
        }
    }
}