首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

責任鏈模式 Java 實戰大全:從擊鼓傳花到 AWT 事件、DOM 事件、紅樓夢案例

     編輯:Java 相關知識

生活隱喻:擊鼓傳花

《紅樓夢》第七十五回描寫賈府擊鼓傳花:花在賈母、賈赦、賈政、寶玉、賈環間循環傳遞,鼓聲停時持花者飲酒。這正是責任鏈模式的完美隱喻:

  • 花 = 請求
  • 傳花者 = 處理者節點
  • 擊鼓者 = 客戶端
  • 飲酒 = 處理邏輯

核心角色與代碼骨架

// 1. 抽象處理者
abstract class Player {
    private Player successor;
    public Player(Player successor) { this.successor = successor; }
    public void setSuccessor(Player successor) { this.successor = successor; }
    public Player getSuccessor() { return successor; }

    // 模板方法:定義處理流程骨架
    public final void handle(int index) {
        if (canHandle(index)) {
            doHandle(index);           // 自己處理
        } else if (successor != null) {
            successor.handle(index);   // 轉發給下家
        } else {
            System.out.println("無人處理,程序結束");
        }
    }
    protected abstract boolean canHandle(int index);  // 判斷是否處理
    protected abstract void doHandle(int index);      // 具體處理邏輯
}

// 2. 具體處理者
class JiaMu extends Player {
    public JiaMu(Player s) { super(s); }
    protected boolean canHandle(int i) { return i == 1; }
    protected void doHandle(int i) { System.out.println("賈母飲酒!"); }
}
class JiaShe extends Player { /* i==2 */ }
class JiaZheng extends Player { /* i==3 */ }
class JiaBaoYu extends Player { /* i==4 */ }
class JiaHuan extends Player { /* i==5 */ }

// 3. 客戶端組裝鏈
public class DrumBeater {
    public static void main(String[] args) {
        Player chain = new JiaMu(
            new JiaShe(
                new JiaZheng(
                    new JiaBaoYu(
                        new JiaHuan(null)  // 尾節點
                    )
                )
            )
        );
        chain.handle(4);  // 請求:第 4 號處理 → 寶玉飲酒
    }
}

純與不純:理論 vs 現實

維度純責任鏈不純責任鏈 (常見)
處理者行為非處理即轉發,二選一可部分處理後轉發,或不處理直接轉發
請求歸宿必被某節點處理可能無人處理(到達尾部仍未處理)
典型案例擊鼓傳花、審批流程AWT 1.0 事件浮升、DOM 事件冒泡、Servlet Filter 鏈

經典系統級應用

1. Java AWT 1.0 事件浮升 (Event Bubbling)

public boolean action(Event event, Object obj) {
    if (event.target == btnOK) { doOKBtnAction(); }
    else if (event.target == btnExit) { doExitBtnAction(); }
    else { return super.action(event, obj); }  // 向父容器傳播
    return true;  // true=停止傳播,false=繼續傳播
}
  • 組件樹 = 責任鏈結構
  • 事件從源組件向上冒泡至頂層窗口
  • 每層可選擇處理、攔截、或繼續冒泡
  • 缺點:基於繼承、性能差 (MouseMove 大量事件冒泡)、耦合組件層次

2. Internet Explorer DOM 事件冒泡

// HTML: 
document.getElementById('b').onclick = function() { alert('Button'); // 1. 目標階段 event.cancelBubble = true; // 阻止冒泡 }; document.getElementById('f').onclick = function() { alert('Form'); }; // 2. 冒泡階段 document.getElementById('d').onclick = function() { alert('Div'); }; // 3. 冒泡階段 document.onclick = function() { alert('Document'); }; // 4. 冒泡階段
  • 事件流:捕獲 → 目標 → 冒泡 (IE 僅支援冒泡)
  • cancelBubble = true 截斷鏈路
  • 現代標準:event.stopPropagation()、addEventListener(type, handler, useCapture)

3. Netscape 事件捕獲 (Event Capturing)

  • 方向相反:window → document → ... → 目標
  • captureEvents(Event.CLICK) 主動捕獲,releaseEvents() 釋放
  • 現代瀏覽器統一支援捕獲+冒泡兩階段

紅樓夢完整案例:動態鏈組裝

// 使用 Spring 管理節點順序,支援運行時動態調整
@Component
public class DrumGameChain {
    @Autowired private List players;  // 按 @Order 排序

    public Player buildChain() {
        Player head = null, prev = null;
        for (Player p : players) {
            if (head == null) head = p;
            else prev.setSuccessor(p);
            prev = p;
        }
        return head;  // 返回鏈頭
    }
}

// 配置順序
@Component @Order(1) public class JiaMu extends Player { ... }
@Component @Order(2) public class JiaShe extends Player { ... }
@Component @Order(3) public class JiaZheng extends Player { ... }
// 新增角色只需加 @Component @Order(n),零代碼修改

墨子守城結構:權限分級審批鏈

《墨子·迎敵祠》:「五步有伍長,十步有什長,百步有佰長,旁有大帥,中有大將」

  • 兵勇申請 → 伍長 → 什長 → 佰長 → 大帥 → 大將
  • 每級權限不同,權限不足向上轉交
  • 審批結果原路返回(雙向鏈)
  • 人員變動 (晉升/調動) 只需調整鏈節點,業務邏輯不變

蘭亭序流觴曲水:純責任鏈變體

  • 酒杯順流而下 = 請求單向傳遞
  • 參加者可選:飲酒 (處理) 或 放行 (轉發)
  • 假設酒杯最終必被飲完 = 純責任鏈
  • 現實中酒杯可能流走無人飲 = 不純

模式協作關係

  • 組合模式:處理者鏈常為樹結構一部分 (AWT 組件樹、DOM 樹)
  • 命令模式:請求對象化 (Command),解耦參數與處理邏輯
  • 模板方法:抽象處理者定義 handle() 骨架,子類實現 canHandle/doHandle

總結

責任鏈模式不僅是「鏈表」,更是「職責分發」的架構哲學。從《紅樓夢》擊鼓傳花到 AWT/DOM 事件模型,從墨子守城審批到現代 Servlet Filter、Spring Interceptor、Netty Pipeline——凡是「請求需經多級處理、處理者動態可變、發送者不關心具體處理者」的場景,皆為責任鏈用武之地。Java 開發者應掌握:Handler 接口設計、successor 引用管理、Spring 動態組裝鏈、FilterChain.doFilter() 標準協議。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved