【C++设计模式】第十三篇:责任链模式(Chain of Responsibility)

注意:复现代码时,确保 VS2022 使用 C++17/20 标准以支持现代特性。

动态传递请求的处理流水线


1. 模式定义与用途

核心思想

  • ​责任链模式:将多个处理对象连成一条链,请求沿链传递直至被处理。每个处理者可选择处理请求或转发给下一处理者。
  • 关键用途
    ​1.解耦请求与处理:发送者无需知道具体处理者。
    ​2.动态调整处理流程:运行时增删处理节点(如日志过滤链、审批流程)。

经典场景

  • 中间件处理HTTP请求(认证、限流、日志)。
  • 多级故障处理(硬件故障 → 软件故障 → 人工介入)。

2. 模式结构解析

UML类图

+---------------------+          +---------------------+  
|      Handler        |          |       Request       |  
+---------------------+          +---------------------+  
| + setNext(h: Handler)|          | + getType(): string |  
| + handle(r: Request)|          +---------------------+  
+---------------------+                    ^  
       ^                                   |  
       |                             +-----+-----+  
       |                             |           |  
+---------------------+    +----------------+ +----------------+  
|  ConcreteHandlerA   |    |  ConcreteHandlerB | |  Client        |  
+---------------------+    +----------------+ +----------------+  
| + handle()          |    | + handle()       | | 创建处理链并触发 |  
+---------------------+    +----------------+ +----------------+  

角色说明

  1. Handler:抽象处理者接口,定义处理方法和设置下一处理者的接口。
  2. ConcreteHandler:具体处理者,实现处理逻辑或转发请求。
  3. Request:封装请求数据,可包含类型、内容等元信息。
  4. Client:组装处理链并触发请求传递。

3. 现代C++实现示例

场景:HTTP请求处理中间件链

​步骤1:定义请求与处理者接口
#include   
#include   
#include   

// 请求对象  
class HttpRequest {  
public:  
    enum class Type { AUTH, RATE_LIMIT, LOGGING };  
    HttpRequest(Type type, const std::string& data)  
        : type_(type), data_(data) {}  

    Type getType() const { return type_; }  
    const std::string& getData() const { return data_; }  

private:  
    Type type_;  
    std::string data_;  
};  

// 处理者接口  
class Handler {  
public:  
    virtual ~Handler() = default;  
    virtual void handle(const HttpRequest& req) = 0;  
    virtual void setNext(std::shared_ptr<Handler> next) { next_ = next; }  

protected:  
    std::shared_ptr<Handler> next_;  
};  
步骤2:实现具体处理者
// 认证中间件  
class AuthHandler : public Handler {  
public:  
    void handle(const HttpRequest& req) override {  
        if (req.getType() == HttpRequest::Type::AUTH) {  
            std::cout << "处理认证请求: " << req.getData() << "\n";  
        } else if (next_) {  
            next_->handle(req);  
        }  
    }  
};  

// 限流中间件  
class RateLimitHandler : public Handler {  
public:  
    void handle(const HttpRequest& req) override {  
        if (req.getType() == HttpRequest::Type::RATE_LIMIT) {  
            std::cout << "处理限流请求: " << req.getData() << "\n";  
        } else if (next_) {  
            next_->handle(req);  
        }  
    }  
};  

// 日志中间件  
class LoggingHandler : public Handler {  
public:  
    void handle(const HttpRequest& req) override {  
        if (req.getType() == HttpRequest::Type::LOGGING) {  
            std::cout << "记录日志: " << req.getData() << "\n";  
        } else if (next_) {  
            next_->handle(req);  
        }  
    }  
};  
步骤3:客户端组装处理链
int main() {  
    // 创建处理者  
    auto auth = std::make_shared<AuthHandler>();  
    auto rateLimit = std::make_shared<RateLimitHandler>();  
    auto logging = std::make_shared<LoggingHandler>();  

    // 构建链:Auth → RateLimit → Logging  
    auth->setNext(rateLimit);  
    rateLimit->setNext(logging);  

    // 模拟请求  
    HttpRequest authReq(HttpRequest::Type::AUTH, "用户登录");  
    HttpRequest logReq(HttpRequest::Type::LOGGING, "访问首页");  

    auth->handle(authReq);  // 认证处理器处理  
    auth->handle(logReq);   // 传递至日志处理器  
}  

/* 输出:  
处理认证请求: 用户登录  
记录日志: 访问首页  
*/  

4. 应用场景示例

场景1:多级审批流程

class PurchaseRequest {  
public:  
    enum class Level { MANAGER, DIRECTOR, CEO };  
    PurchaseRequest(Level level, double amount)  
        : level_(level), amount_(amount) {}  
    Level getLevel() const { return level_; }  
    double getAmount() const { return amount_; }  

private:  
    Level level_;  
    double amount_;  
};  

// 审批处理器基类  
class Approver : public Handler {  
public:  
    void handle(const PurchaseRequest& req) override {  
        if (canApprove(req)) {  
            approve(req);  
        } else if (next_) {  
            next_->handle(req);  
        } else {  
            reject(req);  
        }  
    }  

protected:  
    virtual bool canApprove(const PurchaseRequest& req) = 0;  
    virtual void approve(const PurchaseRequest& req) = 0;  
    virtual void reject(const PurchaseRequest& req) = 0;  
};  

场景2:用户输入验证链

class UserInput {  
public:  
    std::string username;  
    std::string password;  
};  

class Validator : public Handler {  
public:  
    void handle(const UserInput& input) override {  
        if (validate(input)) {  
            if (next_) next_->handle(input);  
        } else {  
            throw std::invalid_argument("验证失败");  
        }  
    }  

protected:  
    virtual bool validate(const UserInput& input) = 0;  
};  

// 具体验证器:非空检查  
class NonEmptyValidator : public Validator {  
    bool validate(const UserInput& input) override {  
        return !input.username.empty() && !input.password.empty();  
    }  
};  

// 具体验证器:密码复杂度  
class PasswordStrengthValidator : public Validator { /*...*/ };  

5. 优缺点分析

​优点 ​缺点
动态增减处理节点,灵活扩展 请求可能未被任何处理者处理(需兜底逻辑)
解耦发送者与接收者 调试复杂(需跟踪链式调用路径)
支持多级处理与优先级控制 长链可能导致性能问题

6. 调试与优化策略

调试技巧(VS2022)​

1.​跟踪处理链传递:
  • 在每个处理者的handle()方法内设置断点,观察请求如何传递。
2.验证处理者顺序:
  • 输出处理者类型名称,确认链的组装顺序正确。
std::cout << "当前处理者: " << typeid(*this).name() << "\n";  

性能优化

1.短路处理:
  • 在特定条件下提前终止链传递(如认证失败直接返回错误)。
void AuthHandler::handle(const HttpRequest& req) {  
    if (!checkToken(req)) {  
        throw std::runtime_error("认证失败");  // 提前终止  
    }  
    next_->handle(req);  
}  
2.并行处理优化:
#include   
void ParallelHandler::handle(const Request& req) {  
    std::for_each(std::execution::par, handlers_.begin(), handlers_.end(),  
        [&req](auto& h) { h->tryHandle(req); });  
}  

你可能感兴趣的:(C++设计模式,c++,设计模式,责任链模式)