【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() | | 创建处理链并触发 |
+---------------------+ +----------------+ +----------------+
角色说明
Handler:抽象处理者接口,定义处理方法和设置下一处理者的接口。-
ConcreteHandler:具体处理者,实现处理逻辑或转发请求。 Request:封装请求数据,可包含类型、内容等元信息。-
Client:组装处理链并触发请求传递。
3. 现代C++实现示例
场景:HTTP请求处理中间件链
步骤1:定义请求与处理者接口
#include <iostream>
#include <memory>
#include <string>
// 请求对象
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 <execution>
void ParallelHandler::handle(const Request& req) {
std::for_each(std::execution::par, handlers_.begin(), handlers_.end(),
[&req](auto& h) { h->tryHandle(req); });
}
更多推荐
所有评论(0)