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

設計模式實作系列(十二):Chain of Responsibility 責任鏈模式 - 讓多個物件有機會處理請求

     編輯:關於C++

模式意圖

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

UML 結構圖

Chain of Responsibility UML

核心解析

  • Handler(處理者): 抽象基類定義 HandleRequest() 並持有 m_pSuccessor 指向下一處理者。
  • 傳遞機制: 具體處理者若能處理則執行,否則呼叫 m_pSuccessor->HandleRequest()。鏈尾若無人處理則請求落空。
  • 動態組裝: 客戶端可靈活組合鏈結順序、增減處理者,無需修改既有類別。
  • 類比: 古裝劇太監傳旨、公司簽核流程、異常處理傳遞、Servlet Filter 鏈。

C++ 完整實作

1. ChainOfResponsibility.h

#ifndef CHAINOFRESPONSIBILITY_H
#define CHAINOFRESPONSIBILITY_H

#include <cstdio>

class Handler {
public:
    Handler(Handler* pSuccessor = nullptr);
    virtual ~Handler();
    virtual void HandleRequest() = 0;
protected:
    Handler* m_pSuccessor;
};

class ConcreteHandler1 : public Handler {
public:
    ConcreteHandler1(Handler* pSuccessor = nullptr) : Handler(pSuccessor) {}
    virtual ~ConcreteHandler1() {}
    virtual void HandleRequest();
};

class ConcreteHandler2 : public Handler {
public:
    ConcreteHandler2(Handler* pSuccessor = nullptr) : Handler(pSuccessor) {}
    virtual ~ConcreteHandler2() {}
    virtual void HandleRequest();
};

#endif

2. ChainOfResponsibility.cpp

#include "ChainOfResponsibility.h"
#include <iostream>

Handler::Handler(Handler* pSuccessor) : m_pSuccessor(pSuccessor) {}
Handler::~Handler() { delete m_pSuccessor; m_pSuccessor = nullptr; }

void ConcreteHandler1::HandleRequest() {
    if (m_pSuccessor) m_pSuccessor->HandleRequest();
    else std::cout << "HandleRequest by ConcreteHandler1\n";
}
void ConcreteHandler2::HandleRequest() {
    if (m_pSuccessor) m_pSuccessor->HandleRequest();
    else std::cout << "HandleRequest by ConcreteHandler2\n";
}

3. Main.cpp

#include "ChainOfResponsibility.h"
#include <cstdlib>

int main() {
    Handler* p1 = new ConcreteHandler1();
    Handler* p2 = new ConcreteHandler2(p1); // p2 -> p1
    p2->HandleRequest(); // p2 無法處理 -> 傳給 p1 -> p1 處理
    delete p2;
    return 0;
}

進階變體與實務建議

  • 純虛/預設實作: 基類可提供預設「傳遞給下一個」實作,子類只需覆寫能處理的情況。
  • 請求物件化: 將請求封裝為 Request 類別(含型別、資料、優先級),處理者根據請求內容決定是否處理。
  • 責任鏈 vs 裝飾模式: 裝飾模式所有層必須執行(前/後處理),責任鏈只有一層處理(或無人處理)。
  • 現代 C++: 使用 std::function + std::vector 組裝管線,或採用中介軟體模式。

適用場景

  • 多條件過濾/驗證(如輸入合法性檢查、權限校驗)。
  • 事件處理傳遞(GUI 事件冒泡、網路封包處理鏈)。
  • 簽核流程、異常處理傳遞、日誌分級處理。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved