当前位置: 首页 > news >正文

设计模式(C++)详解——职责链模式 (Chain of Responsibility)(1)

职责链模式 (Chain of Responsibility) 全方位生动解析

<摘要>

职责链模式是一种行为设计模式,它就像公司的审批流程或者医院的挂号分诊系统:当一个请求到来时,它会在一条处理链上依次传递,每个处理者都有机会处理这个请求,直到某个处理者接手为止。这种模式将请求的发送者和接收者解耦,让多个对象都有机会处理请求,同时避免了复杂的条件判断语句。从GUI事件处理到Web中间件,从工作流引擎到异常处理系统,职责链模式让软件系统更加灵活和可扩展。


<解析>

1. 背景与核心概念:处理流程的智能化

1.1 模式起源与现实比喻

想象一下医院的急诊科分诊系统:

  • 护士预检:初步判断病情严重程度
  • 普通医生:处理常见病症
  • 专科医生:处理复杂病例
  • 主任医师:处理疑难杂症

病人(请求)按照病情严重程度在医护人员的"链条"上流动,直到找到合适的处理者。这就是职责链模式在现实世界的完美体现!

在软件世界中,职责链模式最早在GoF的《设计模式》中提出,用于解决:

  • 请求发送者与接收者的耦合问题
  • 动态指定请求处理者
  • 避免复杂的条件分支判断
1.2 核心概念与UML结构

职责链模式包含三个核心角色:

successor
«abstract»
Handler
-successor: Handler*
+setSuccessor(Handler*)
+handleRequest(Request)
ConcreteHandlerA
+handleRequest(Request)
ConcreteHandlerB
+handleRequest(Request)
Request
-type: string
-content: string
+getType()
+getContent()

核心角色解析:

  1. Handler(抽象处理者)

    • 定义处理请求的接口
    • 持有下一个处理者的引用(successor)
    • 可以设置后继处理者
  2. ConcreteHandler(具体处理者)

    • 实现处理请求的具体逻辑
    • 判断自己是否能处理该请求
    • 如果可以处理则处理,否则传递给后继者
  3. 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天请假,转交上级...
请假天数过长,需要董事会审批!

时序图

ClientGroupLeaderManagerDirectorprocessRequest(2天)审批通过结果processRequest(5天)processRequest(5天)审批通过结果processRequest(10天)processRequest(10天)processRequest(10天)审批通过结果ClientGroupLeaderManagerDirector
案例二: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 实现建议
  1. 明确处理顺序:确保链的顺序符合业务逻辑
  2. 避免循环引用:使用智能指针管理生命周期
  3. 提供默认处理:链的末端应该有默认处理器
  4. 记录处理日志:便于调试和监控
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);                  // 路由处理

总结

职责链模式是一种强大而灵活的行为设计模式,它通过将处理者组织成链式结构,实现了请求发送者与接收者的解耦。这种模式的核心价值在于:

  1. 灵活性:可以动态调整处理流程
  2. 可扩展性:新增处理者非常容易
  3. 职责清晰:每个处理者专注于自己的职责范围
  4. 降低耦合:发送者不需要知道具体的处理细节

从企业审批流程到Web中间件,从异常处理到事件系统,职责链模式在软件开发的各个领域都有广泛应用。掌握这一模式,能够帮助你设计出更加灵活、可维护的系统架构。

记住职责链模式的精髓:让请求在链上流动,直到找到合适的处理者。这种"接力棒"式的处理方式,既优雅又实用,是现代软件设计中不可或缺的工具之一。

http://www.dtcms.com/a/398341.html

相关文章:

  • 酒店网站免费建设国际新闻今天最新
  • 企业产品网络安全日志9月23日-WAF应急
  • 嵌入式硬件工程师:绝缘栅型场效应管
  • HTTPS 请求抓包实战,从请求捕获到解密分析的逐步流程与工具组合(https 请求抓包、iOS 真机、SSL Pinning 排查)
  • 怎么学习cuda?
  • iOS 开发指南全解析 从入门到应用上架、Xcode 使用教程、ipa 打包上传与 App Store 审核实战经验
  • iOS 26 帧率测试实战指南,Liquid Glass 动画性能、滚动滑动帧率对比、旧机型流畅性与 uni-app 优化策略
  • 在网站上签失业保险怎样做网站对公司的重要性
  • php网站模板 php网站源码 PHP源码网
  • 万能PDF工具箱(PDF Candy)安装教程
  • 两款功能强大的密码学工具箱
  • umijs 4.0学习 - 路由
  • 【Java】P7 Java数组完全指南:从基础到进阶
  • PTZ相机AI相关的知识体系
  • Python 2025:新型解释器与性能优化实战
  • go 持续集成、持续部署之gitlab流水线+docker-compose踩坑之旅
  • 声明式事务5
  • 时序数据库选型指南:Apache IoTDB引领数字化转型新时代
  • [Android] apkm安装器 APKMirror Installer v1.10.1
  • spring boot项目使用Torna生成在线接口文档
  • 两学一做教育纪实评价系统网站店铺小程序如何开通
  • 10分钟快速部署PHP+Nginx+MySQL+Redis开发环境
  • 通过智享直播,企业如何实现精准的受众定位与内容分发
  • 【Prompt学习技能树地图】零样本与少样本提示技术实战:原理、应用与调优
  • group_points自定义tensorrt算子编写
  • 20250925问答课题-多标签分类模型
  • 唯品会库存API集成问题与技术方案解析
  • Python开发一个系统
  • 02-教务管理系统(选课管理系统)
  • 从入门到精通:逆向工程完全工具指南与桌面环境搭建