核心思想
責任鏈模式是一種行為設計模式,允許多個對象都有機會處理請求,從而避免請求的發送者與接收者之間的耦合。請求沿著處理鏈傳遞,直到某個對象處理它為止。
解決的問題
?解耦請求發送者與處理者:請求的發送者無需知道具體由哪個對象處理請求。
?動態分配責任:可以在運行時動態調整處理鏈,靈活添加或移除處理者。
?避免硬編碼:避免將請求處理邏輯硬編碼在某個類中,提高代碼的可擴展性和可維護性。
使用場景
?多級審批流程:如請假審批、報銷審批等,每一級領導都可以處理或傳遞給上級。
?事件處理系統:如 GUI 事件處理,事件可以沿著組件鏈傳遞,直到被處理。
?日志記錄系統:不同級別的日志消息可以被不同的日志處理器處理。
?過濾器鏈:如 HTTP 請求過濾器,每個過濾器可以處理請求或傳遞給下一個過濾器。
優點
?解耦:請求發送者與處理者解耦,發送者無需知道具體處理者。
?動態性:可以在運行時動態調整處理鏈。
?單一職責:每個處理者只關注自己的職責,符合單一職責原則。
缺點
?性能問題:如果鏈過長,可能導致請求傳遞效率低下。
?不確定性:請求可能未被任何處理者處理,需要額外邏輯處理這種情況。
示例代碼
以下是一個簡單的責任鏈模式示例,模擬多級審批流程:
#include <iostream>
#include <memory>
#include <string>// 請求類
class Request {
public:Request(const std::string& content, int level) : content_(content), level_(level) {}std::string getContent() const { return content_; }int getLevel() const { return level_; }private:std::string content_; // 請求內容int level_; // 請求級別
};// 處理者基類
class Handler {
public:virtual ~Handler() = default;void setNext(std::shared_ptr<Handler> next) { next_ = next; }virtual void handleRequest(const Request& request) {if (next_) {next_->handleRequest(request); // 傳遞給下一個處理者} else {std::cout << "Request未被處理: " << request.getContent() << std::endl;}}protected:std::shared_ptr<Handler> next_; // 下一個處理者
};// 具體處理者:經理
class Manager : public Handler {
public:void handleRequest(const Request& request) override {if (request.getLevel() <= 1) {std::cout << "經理處理請求: " << request.getContent() << std::endl;} else {Handler::handleRequest(request); // 傳遞給下一個處理者}}
};// 具體處理者:總監
class Director : public Handler {
public:void handleRequest(const Request& request) override {if (request.getLevel() <= 2) {std::cout << "總監處理請求: " << request.getContent() << std::endl;} else {Handler::handleRequest(request); // 傳遞給下一個處理者}}
};// 具體處理者:CEO
class CEO : public Handler {
public:void handleRequest(const Request& request) override {if (request.getLevel() <= 3) {std::cout << "CEO處理請求: " << request.getContent() << std::endl;} else {Handler::handleRequest(request); // 傳遞給下一個處理者}}
};int main() {// 創建處理鏈auto manager = std::make_shared<Manager>();auto director = std::make_shared<Director>();auto ceo = std::make_shared<CEO>();manager->setNext(director);director->setNext(ceo);// 創建請求Request request1("請假1天", 1); // 經理處理Request request2("請假3天", 2); // 總監處理Request request3("請假10天", 3); // CEO處理Request request4("請假30天", 4); // 未被處理// 處理請求manager->handleRequest(request1);manager->handleRequest(request2);manager->handleRequest(request3);manager->handleRequest(request4);return 0;
}
輸出結果
經理處理請求: 請假1天
總監處理請求: 請假3天
CEO處理請求: 請假10天
Request未被處理: 請假30天
代碼解析
?Request 類:封裝請求內容和級別。
?Handler 基類:定義處理請求的接口,并持有下一個處理者的指針。
?具體處理者 Manager、Director、CEO?:實現自己的處理邏輯,若無法處理則傳遞給下一個處理者。
?處理鏈:通過 setNext 方法動態構建處理鏈。