设计模式(C++)详解——职责链模式 (Chain of Responsibility)(1)
职责链模式 (Chain of Responsibility) 全方位生动解析
<摘要>
职责链模式是一种行为设计模式,它就像公司的审批流程或者医院的挂号分诊系统:当一个请求到来时,它会在一条处理链上依次传递,每个处理者都有机会处理这个请求,直到某个处理者接手为止。这种模式将请求的发送者和接收者解耦,让多个对象都有机会处理请求,同时避免了复杂的条件判断语句。从GUI事件处理到Web中间件,从工作流引擎到异常处理系统,职责链模式让软件系统更加灵活和可扩展。
<解析>
1. 背景与核心概念:处理流程的智能化
1.1 模式起源与现实比喻
想象一下医院的急诊科分诊系统:
- 护士预检:初步判断病情严重程度
- 普通医生:处理常见病症
- 专科医生:处理复杂病例
- 主任医师:处理疑难杂症
病人(请求)按照病情严重程度在医护人员的"链条"上流动,直到找到合适的处理者。这就是职责链模式在现实世界的完美体现!
在软件世界中,职责链模式最早在GoF的《设计模式》中提出,用于解决:
- 请求发送者与接收者的耦合问题
- 动态指定请求处理者
- 避免复杂的条件分支判断
1.2 核心概念与UML结构
职责链模式包含三个核心角色:
核心角色解析:
-
Handler(抽象处理者)
- 定义处理请求的接口
- 持有下一个处理者的引用(successor)
- 可以设置后继处理者
-
ConcreteHandler(具体处理者)
- 实现处理请求的具体逻辑
- 判断自己是否能处理该请求
- 如果可以处理则处理,否则传递给后继者
-
Request(请求)
- 包含请求相关的信息和数据
- 可以被处理者检查和操作
2. 设计意图与考量:为什么需要职责链?
2.1 核心目标与优势
主要意图:解耦请求发送者与接收者,让多个对象都有机会处理请求。
核心优势:
- ✅ 降低耦合度:发送者不需要知道具体由哪个处理者处理
- ✅ 增强灵活性:可以动态调整处理链
- ✅ 简化对象职责:每个处理者只关注自己能处理的请求
- ✅ 便于扩展:新增处理者很容易
2.2 设计考量与权衡
适用场景:
- 有多个对象可以处理同一请求,但具体由谁处理在运行时确定
- 需要动态指定处理者集合
- 不想让请求发送者知道具体的处理者
不适用场景:
- 每个请求只能被一个处理者处理时
- 请求必须有明确的处理者时
与相关模式对比:
模式 | 关注点 | 特点 |
---|---|---|
职责链 | 请求处理流程 | 多个处理者,依次尝试 |
命令模式 | 请求封装 | 将请求封装为对象 |
策略模式 | 算法选择 | 多个算法,选择一个执行 |
3. 实例与应用场景
让我们通过几个生动的例子来理解职责链模式的实际应用。
案例一:请假审批系统
场景:公司请假系统,不同时长的请假需要不同级别的领导审批:
- 1-3天:组长审批
- 4-7天:经理审批
- 8天以上:总监审批
#include <iostream>
#include <string>
#include <memory>// 请求类:请假申请
class LeaveRequest {
public:LeaveRequest(const std::string& name, int days, const std::string& reason): m_name(name), m_days(days), m_reason(reason) {}const std::string& getName() const { return m_name; }int getDays() const { return m_days; }const std::string& getReason() const { return m_reason; }private:std::string m_name; // 员工姓名int m_days; // 请假天数std::string m_reason; // 请假原因
};// 抽象处理者
class Approver {
public:virtual ~Approver() = default;void setSuccessor(std::shared_ptr<Approver> successor) {m_successor = successor;}virtual void processRequest(const LeaveRequest& request) = 0;protected:std::shared_ptr<Approver> m_successor;
};// 具体处理者:组长
class GroupLeader : public Approver {
public:GroupLeader(const std::string& name) : m_name(name) {}void processRequest(const LeaveRequest& request) override {if (request.getDays() <= 3) {std::cout << "组长" << m_name << "审批了" << request.getName() << "的请假申请,天数:" << request.getDays() << ",理由:" << request.getReason() << std::endl;} else if (m_successor != nullptr) {std::cout << "组长" << m_name << "无权限审批" << request.getDays() << "天请假,转交上级..." << std::endl;m_successor->processRequest(request);} else {std::cout << "无人能处理此请假申请!" << std::endl;}}private:std::string m_name;
};// 具体处理者:经理
class Manager : public Approver {
public:Manager(const std::string& name) : m_name(name) {}void processRequest(const LeaveRequest& request) override {if (request.getDays() <= 7) {std::cout << "经理" << m_name << "审批了" << request.getName() << "的请假申请,天数:" << request.getDays() << ",理由:" << request.getReason() << std::endl;} else if (m_successor != nullptr) {std::cout << "经理" << m_name << "无权限审批" << request.getDays() << "天请假,转交上级..." << std::endl;m_successor->processRequest(request);} else {std::cout << "无人能处理此请假申请!" << std::endl;}}private:std::string m_name;
};// 具体处理者:总监
class Director : public Approver {
public:Director(const std::string& name) : m_name(name) {}void processRequest(const LeaveRequest& request) override {if (request.getDays() <= 15) {std::cout << "总监" << m_name << "审批了" << request.getName() << "的请假申请,天数:" << request.getDays() << ",理由:" << request.getReason() << std::endl;} else {std::cout << "请假天数过长,需要董事会审批!" << std::endl;}}private:std::string m_name;
};// 客户端代码
int main() {std::cout << "=== 公司请假审批系统 ===" << std::endl;// 创建审批链:组长 -> 经理 -> 总监auto groupLeader = std::make_shared<GroupLeader>("张组长");auto manager = std::make_shared<Manager>("李经理");auto director = std::make_shared<Director>("王总监");groupLeader->setSuccessor(manager);manager->setSuccessor(director);// 创建请假申请LeaveRequest request1("张三", 2, "感冒发烧");LeaveRequest request2("李四", 5, "结婚");LeaveRequest request3("王五", 10, "出国旅游");LeaveRequest request4("赵六", 20, "长期病假");// 处理请假申请std::cout << "\n1. 处理张三的请假:" << std::endl;groupLeader->processRequest(request1);std::cout << "\n2. 处理李四的请假:" << std::endl;groupLeader->processRequest(request2);std::cout << "\n3. 处理王五的请假:" << std::endl;groupLeader->processRequest(request3);std::cout << "\n4. 处理赵六的请假:" << std::endl;groupLeader->processRequest(request4);return 0;
}
输出结果:
=== 公司请假审批系统 ===1. 处理张三的请假:
组长张组长审批了张三的请假申请,天数:2,理由:感冒发烧2. 处理李四的请假:
组长张组长无权限审批5天请假,转交上级...
经理李经理审批了李四的请假申请,天数:5,理由:结婚3. 处理王五的请假:
组长张组长无权限审批10天请假,转交上级...
经理李经理无权限审批10天请假,转交上级...
总监王总监审批了王五的请假申请,天数:10,理由:出国旅游4. 处理赵六的请假:
组长张组长无权限审批20天请假,转交上级...
经理李经理无权限审批20天请假,转交上级...
请假天数过长,需要董事会审批!
时序图:
案例二:Web请求过滤器链
场景:Web服务器处理HTTP请求时,需要经过一系列过滤器:身份验证、日志记录、数据压缩、缓存等。
#include <iostream>
#include <string>
#include <vector>
#include <memory>// HTTP请求类
class HttpRequest {
public:HttpRequest(const std::string& url, const std::string& method, const std::string& body = ""): m_url(url), m_method(method), m_body(body), m_authenticated(false) {}const std::string& getUrl() const { return m_url; }const std::string& getMethod() const { return m_method; }const std::string& getBody() const { return m_body; }bool isAuthenticated() const { return m_authenticated; }void setAuthenticated(bool auth) { m_authenticated = auth; }void setBody(const std::string& body) { m_body = body; }private:std::string m_url;std::string m_method;std::string m_body;bool m_authenticated;
};// HTTP响应类
class HttpResponse {
public:HttpResponse() : m_statusCode(200), m_body("") {}void setStatusCode(int code) { m_statusCode = code; }void setBody(const std::string& body) { m_body = body; }int getStatusCode() const { return m_statusCode; }const std::string& getBody() const { return m_body; }private:int m_statusCode;std::string m_body;
};// 抽象过滤器
class Filter {
public:virtual ~Filter() = default;virtual void doFilter(HttpRequest& request, HttpResponse& response, std::shared_ptr<Filter> next) = 0;
};// 具体过滤器:认证过滤器
class AuthenticationFilter : public Filter {
public:void doFilter(HttpRequest& request, HttpResponse& response,std::shared_ptr<Filter> next) override {std::cout << "[认证过滤器] 检查请求认证..." << std::endl;// 模拟认证检查if (request.getUrl().find("/admin") != std::string::npos) {if (request.isAuthenticated()) {std::cout << "[认证过滤器] 认证通过" << std::endl;if (next != nullptr) {next->doFilter(request, response, next->getNext());}} else {std::cout << "[认证过滤器] 认证失败,返回401" << std::endl;response.setStatusCode(401);response.setBody("Unauthorized");}} else {std::cout << "[认证过滤器] 公开资源,跳过认证" << std::endl;if (next != nullptr) {next->doFilter(request, response, next->getNext());}}}void setNext(std::shared_ptr<Filter> next) { m_next = next; }std::shared_ptr<Filter> getNext() { return m_next; }private:std::shared_ptr<Filter> m_next;
};// 具体过滤器:日志过滤器
class LoggingFilter : public Filter {
public:void doFilter(HttpRequest& request, HttpResponse& response,std::shared_ptr<Filter> next) override {std::cout << "[日志过滤器] 记录请求: " << request.getMethod() << " " << request.getUrl() << std::endl;// 记录开始时间auto start = std::chrono::steady_clock::now();if (next != nullptr) {next->doFilter(request, response, next->getNext());}// 记录处理时间auto end = std::chrono::steady_clock::now();auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);std::cout << "[日志过滤器] 请求处理时间: " << duration.count() << "ms" << std::endl;}void setNext(std::shared_ptr<Filter> next) { m_next = next; }std::shared_ptr<Filter> getNext() { return m_next; }private:std::shared_ptr<Filter> m_next;
};// 具体过滤器:压缩过滤器
class CompressionFilter : public Filter {
public:void doFilter(HttpRequest& request, HttpResponse& response,std::shared_ptr<Filter> next) override {std::cout << "[压缩过滤器] 检查压缩需求..." << std::endl;if (next != nullptr) {next->doFilter(request, response, next->getNext());}// 对响应进行压缩(模拟)if (response.getBody().length() > 100) {std::cout << "[压缩过滤器] 对响应进行压缩" << std::endl;response.setBody("compressed(" + response.getBody() + ")");}}void setNext(std::shared_ptr<Filter> next) { m_next = next; }std::shared_ptr<Filter> getNext() { return m_next; }private:std::shared_ptr<Filter> m_next;
};// 业务处理器
class BusinessHandler : public Filter {
public:void doFilter(HttpRequest& request, HttpResponse& response,std::shared_ptr<Filter> next) override {std::cout << "[业务处理器] 处理业务逻辑..." << std::endl;// 模拟业务处理if (request.getUrl() == "/api/data") {response.setBody("业务数据结果");} else if (request.getUrl() == "/admin/dashboard") {response.setBody("管理员面板");} else {response.setStatusCode(404);response.setBody("Not Found");}// 业务处理器是链的末端,没有next}void setNext(std::shared_ptr<Filter> next) { m_next = next; }std::shared_ptr<Filter> getNext() { return m_next; }private:std::shared_ptr<Filter> m_next;
};// 过滤器链管理器
class FilterChain {
public:void addFilter(std::shared_ptr<Filter> filter) {m_filters.push_back(filter);}void doFilter(HttpRequest& request, HttpResponse& response) {if (m_filters.empty()) return;// 构建链式关系for (size_t i = 0; i < m_filters.size() - 1; ++i) {m_filters[i]->setNext(m_filters[i + 1]);}// 开始执行过滤器链m_filters[0]->doFilter(request, response, m_filters[0]->getNext());}private:std::vector<std::shared_ptr<Filter>> m_filters;
};// 客户端代码
int main() {std::cout << "=== Web服务器过滤器链演示 ===" << std::endl;// 创建过滤器链FilterChain chain;chain.addFilter(std::make_shared<LoggingFilter>());chain.addFilter(std::make_shared<AuthenticationFilter>());chain.addFilter(std::make_shared<CompressionFilter>());chain.addFilter(std::make_shared<BusinessHandler>());// 测试请求1:公开APIstd::cout << "\n--- 测试1:公开API请求 ---" << std::endl;HttpRequest request1("/api/data", "GET");HttpResponse response1;chain.doFilter(request1, response1);std::cout << "响应状态: " << response1.getStatusCode() << ", 内容: " << response1.getBody() << std::endl;// 测试请求2:需要认证的管理员页面(未认证)std::cout << "\n--- 测试2:未认证的管理员请求 ---" << std::endl;HttpRequest request2("/admin/dashboard", "GET");HttpResponse response2;chain.doFilter(request2, response2);std::cout << "响应状态: " << response2.getStatusCode() << ", 内容: " << response2.getBody() << std::endl;// 测试请求3:需要认证的管理员页面(已认证)std::cout << "\n--- 测试3:已认证的管理员请求 ---" << std::endl;HttpRequest request3("/admin/dashboard", "GET");request3.setAuthenticated(true);HttpResponse response3;chain.doFilter(request3, response3);std::cout << "响应状态: " << response3.getStatusCode() << ", 内容: " << response3.getBody() << std::endl;return 0;
}
案例三:异常处理系统
场景:软件系统中的异常处理,不同级别的异常由不同层次的处理器处理。
#include <iostream>
#include <memory>
#include <stdexcept>// 异常类层次结构
class ApplicationException : public std::exception {
public:ApplicationException(const std::string& msg, int severity) : m_message(msg), m_severity(severity) {}const char* what() const noexcept override { return m_message.c_str(); }int getSeverity() const { return m_severity; }private:std::string m_message;int m_severity;
};class NetworkException : public ApplicationException {
public:NetworkException(const std::string& msg) : ApplicationException(msg, 3) {} // 严重程度:3
};class DatabaseException : public ApplicationException {
public:DatabaseException(const std::string& msg) : ApplicationException(msg, 4) {} // 严重程度:4
};class CriticalSystemException : public ApplicationException {
public:CriticalSystemException(const std::string& msg) : ApplicationException(msg, 5) {} // 严重程度:5
};// 异常处理器抽象类
class ExceptionHandler {
public:virtual ~ExceptionHandler() = default;void setNextHandler(std::shared_ptr<ExceptionHandler> next) {m_nextHandler = next;}virtual bool handleException(const ApplicationException& e) = 0;protected:std::shared_ptr<ExceptionHandler> m_nextHandler;
};// 具体处理器:日志记录处理器
class LoggingHandler : public ExceptionHandler {
public:bool handleException(const ApplicationException& e) override {std::cout << "[日志处理器] 记录异常: " << e.what() << " (严重程度: " << e.getSeverity() << ")" << std::endl;// 总是记录日志,然后传递给下一个处理器if (m_nextHandler) {return m_nextHandler->handleException(e);}return true; // 链的末端,处理完成}
};// 具体处理器:网络异常处理器
class NetworkExceptionHandler : public ExceptionHandler {
public:bool handleException(const ApplicationException& e) override {if (const NetworkException* ne = dynamic_cast<const NetworkException*>(&e)) {std::cout << "[网络异常处理器] 处理网络异常: " << e.what() << std::endl;// 模拟重试逻辑std::cout << "尝试重新连接网络..." << std::endl;return true; // 已处理}// 如果不是网络异常,传递给下一个处理器if (m_nextHandler) {return m_nextHandler->handleException(e);}return false; // 无人处理}
};// 具体处理器:数据库异常处理器
class DatabaseExceptionHandler : public ExceptionHandler {
public:bool handleException(const ApplicationException& e) override {if (const DatabaseException* de = dynamic_cast<const DatabaseException*>(&e)) {std::cout << "[数据库异常处理器] 处理数据库异常: " << e.what() << std::endl;// 模拟数据库恢复逻辑std::cout << "尝试重新连接数据库..." << std::endl;return true; // 已处理}if (m_nextHandler) {return m_nextHandler->handleException(e);}return false;}
};// 具体处理器:严重系统异常处理器
class CriticalExceptionHandler : public ExceptionHandler {
public:bool handleException(const ApplicationException& e) override {if (e.getSeverity() >= 5) {std::cout << "[严重异常处理器] 处理严重异常: " << e.what() << std::endl;std::cout << "发送警报邮件,准备系统重启..." << std::endl;return true;}if (m_nextHandler) {return m_nextHandler->handleException(e);}return false;}
};// 具体处理器:默认异常处理器
class DefaultExceptionHandler : public ExceptionHandler {
public:bool handleException(const ApplicationException& e) override {std::cout << "[默认异常处理器] 处理未知异常: " << e.what() << std::endl;std::cout << "执行默认恢复操作..." << std::endl;return true; // 总是能处理}
};// 异常处理管理器
class ExceptionManager {
public:ExceptionManager() {// 构建处理链:日志 -> 网络 -> 数据库 -> 严重 -> 默认m_handlers.push_back(std::make_shared<LoggingHandler>());m_handlers.push_back(std::make_shared<NetworkExceptionHandler>());m_handlers.push_back(std::make_shared<DatabaseExceptionHandler>());m_handlers.push_back(std::make_shared<CriticalExceptionHandler>());m_handlers.push_back(std::make_shared<DefaultExceptionHandler>());// 建立链式关系for (size_t i = 0; i < m_handlers.size() - 1; ++i) {m_handlers[i]->setNextHandler(m_handlers[i + 1]);}}void handleException(const ApplicationException& e) {std::cout << "=== 异常处理开始 ===" << std::endl;if (!m_handlers.empty()) {bool handled = m_handlers[0]->handleException(e);if (handled) {std::cout << "异常处理完成" << std::endl;} else {std::cout << "异常未能处理" << std::endl;}}std::cout << "=== 异常处理结束 ===\n" << std::endl;}private:std::vector<std::shared_ptr<ExceptionHandler>> m_handlers;
};// 客户端代码
int main() {std::cout << "=== 异常处理职责链演示 ===" << std::endl;ExceptionManager exceptionManager;// 测试各种异常std::cout << "测试1: 网络异常" << std::endl;NetworkException netException("连接超时");exceptionManager.handleException(netException);std::cout << "测试2: 数据库异常" << std::endl;DatabaseException dbException("数据库连接失败");exceptionManager.handleException(dbException);std::cout << "测试3: 严重系统异常" << std::endl;CriticalSystemException criticalException("内存溢出");exceptionManager.handleException(criticalException);std::cout << "测试4: 未知类型异常" << std::endl;ApplicationException unknownException("未知错误", 2);exceptionManager.handleException(unknownException);return 0;
}
4. 高级应用与变体
4.1 功能链 vs. 处理链
职责链模式有两种主要变体:
功能链(Functional Chain):每个处理者都对请求进行某种处理
// 如Web过滤器链,每个过滤器都处理请求
class FunctionalHandler {
public:virtual void process(Request& request) {// 处理请求...if (m_next) m_next->process(request);// 可能还有后处理...}
};
处理链(Handler Chain):直到某个处理者处理请求为止
// 如审批系统,找到能处理的就停止
class HandlerChain {
public:virtual bool handle(Request& request) {if (canHandle(request)) {// 处理请求return true;} else if (m_next) {return m_next->handle(request);}return false;}
};
4.2 动态链构建
职责链可以在运行时动态构建和修改:
class DynamicChain {
public:void addHandler(std::shared_ptr<Handler> handler) {m_handlers.push_back(handler);}void removeHandler(const std::string& handlerType) {m_handlers.erase(std::remove_if(m_handlers.begin(), m_handlers.end(),[&](auto& h) { return h->getType() == handlerType; }),m_handlers.end());}void insertHandler(int position, std::shared_ptr<Handler> handler) {m_handlers.insert(m_handlers.begin() + position, handler);}
};
5. 最佳实践与注意事项
5.1 实现建议
- 明确处理顺序:确保链的顺序符合业务逻辑
- 避免循环引用:使用智能指针管理生命周期
- 提供默认处理:链的末端应该有默认处理器
- 记录处理日志:便于调试和监控
5.2 性能考虑
// 优化:缓存处理能力判断
class OptimizedHandler : public Handler {
public:bool canHandle(const Request& request) override {// 缓存判断结果,避免重复计算auto it = m_cache.find(request.getType());if (it != m_cache.end()) {return it->second;}bool result = // 复杂的判断逻辑m_cache[request.getType()] = result;return result;}private:std::unordered_map<std::string, bool> m_cache;
};
6. 在现代框架中的应用
6.1 Spring框架的拦截器链
// Spring MVC的拦截器链就是职责链模式的典型应用
public class AuthenticationInterceptor implements HandlerInterceptor {public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {// 认证逻辑if (!isAuthenticated(request)) {response.sendError(401);return false; // 中断链}return true; // 继续链}
}
6.2 Node.js的中间件系统
// Express.js中间件就是职责链模式
app.use(loggerMiddleware); // 日志
app.use(authenticationMiddleware); // 认证
app.use(compressionMiddleware); // 压缩
app.use(router); // 路由处理
总结
职责链模式是一种强大而灵活的行为设计模式,它通过将处理者组织成链式结构,实现了请求发送者与接收者的解耦。这种模式的核心价值在于:
- 灵活性:可以动态调整处理流程
- 可扩展性:新增处理者非常容易
- 职责清晰:每个处理者专注于自己的职责范围
- 降低耦合:发送者不需要知道具体的处理细节
从企业审批流程到Web中间件,从异常处理到事件系统,职责链模式在软件开发的各个领域都有广泛应用。掌握这一模式,能够帮助你设计出更加灵活、可维护的系统架构。
记住职责链模式的精髓:让请求在链上流动,直到找到合适的处理者。这种"接力棒"式的处理方式,既优雅又实用,是现代软件设计中不可或缺的工具之一。