ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

C++职责链模式解析与日志系统实战

C++职责链模式解析与日志系统实战 1. 职责链模式基础解析在C开发中职责链模式Chain of Responsibility是一种典型的行为型设计模式它通过构建一条处理者链来解耦请求发送者和接收者。想象一下公司报销流程普通员工提交申请后会根据金额大小自动流转到不同层级的主管——部门经理处理小额报销财务总监审批大额支出CEO决策特大金额申请。这种分级处理机制正是职责链模式的现实映射。职责链模式的核心价值在于动态可配置性处理链可以在运行时动态调整比如新增审计节点或调整审批阈值单一职责原则每个处理者只需关注自己职责范围内的请求解耦优势发送者无需知道具体由哪个处理者执行只需将请求放入链中典型应用场景包括多级审批系统如OA系统中的工作流事件处理管道如GUI中的事件冒泡机制日志记录器根据日志级别选择不同记录方式异常处理try-catch块本质上就是责任链2. C实现方案设计2.1 类结构设计标准实现包含三个关键组件// 抽象处理者基类 class Handler { public: virtual ~Handler() default; virtual void setNext(Handler* next) 0; virtual void handleRequest(const Request req) 0; }; // 具体处理者实现 class ConcreteHandlerA : public Handler { Handler* next_ nullptr; public: void setNext(Handler* next) override { next_ next; } void handleRequest(const Request req) override { if (canHandle(req)) { // 处理请求 } else if (next_) { next_-handleRequest(req); // 传递请求 } else { // 链尾处理逻辑 } } private: bool canHandle(const Request req) const { // 判断条件 } }; // 客户端使用示例 void clientCode() { auto h1 std::make_uniqueConcreteHandlerA(); auto h2 std::make_uniqueConcreteHandlerB(); h1-setNext(h2.get()); Request req; h1-handleRequest(req); }2.2 现代C优化技巧使用智能指针管理链生命周期class Handler { std::shared_ptrHandler next_; public: void setNext(std::shared_ptrHandler next) { next_ std::move(next); } void handleRequest(const Request req) { if (/* 处理条件 */) { // 处理逻辑 } else if (next_) { next_-handleRequest(req); } } };引入模板实现通用处理链templatetypename T class GenericHandler { std::functionbool(const T) predicate_; std::unique_ptrGenericHandler next_; public: GenericHandler(std::functionbool(const T) pred) : predicate_(std::move(pred)) {} void setNext(std::unique_ptrGenericHandler next) { next_ std::move(next); } void handle(const T request) { if (predicate_(request)) { // 处理逻辑 } else if (next_) { next_-handle(request); } } };3. 实战案例日志系统实现3.1 需求分析实现分级日志系统要求DEBUG级别输出到控制台和文件WARNING级别额外发送邮件通知ERROR级别额外触发短信报警3.2 完整实现代码enum class LogLevel { DEBUG, WARNING, ERROR }; struct LogMessage { LogLevel level; std::string content; std::time_t timestamp; }; class Logger { protected: std::unique_ptrLogger next_; public: virtual ~Logger() default; void setNext(std::unique_ptrLogger next) { next_ std::move(next); } void log(const LogMessage msg) { if (shouldHandle(msg)) { writeLog(msg); } if (next_) { next_-log(msg); } } protected: virtual bool shouldHandle(const LogMessage msg) const 0; virtual void writeLog(const LogMessage msg) 0; }; class ConsoleLogger : public Logger { protected: bool shouldHandle(const LogMessage) const override { return true; // 始终处理 } void writeLog(const LogMessage msg) override { std::cout std::put_time(std::localtime(msg.timestamp), %F %T) [ toString(msg.level) ] msg.content std::endl; } private: static std::string toString(LogLevel level) { static const char* names[] {DEBUG, WARNING, ERROR}; return names[static_castint(level)]; } }; class FileLogger : public Logger { std::ofstream logFile_; public: explicit FileLogger(const std::string filename) : logFile_(filename, std::ios::app) {} protected: bool shouldHandle(const LogMessage msg) const override { return msg.level LogLevel::DEBUG; } void writeLog(const LogMessage msg) override { logFile_ std::put_time(std::localtime(msg.timestamp), %F %T) [ toString(msg.level) ] msg.content std::endl; } }; class EmailNotifier : public Logger { protected: bool shouldHandle(const LogMessage msg) const override { return msg.level LogLevel::WARNING; } void writeLog(const LogMessage msg) override { // 模拟邮件发送 std::cout [Email] Critical Log: msg.content std::endl; } }; class SmsAlerter : public Logger { protected: bool shouldHandle(const LogMessage msg) const override { return msg.level LogLevel::ERROR; } void writeLog(const LogMessage msg) override { // 模拟短信发送 std::cout [SMS] EMERGENCY: msg.content std::endl; } }; // 构建日志处理链 auto createLoggerChain() { auto console std::make_uniqueConsoleLogger(); auto file std::make_uniqueFileLogger(app.log); auto email std::make_uniqueEmailNotifier(); auto sms std::make_uniqueSmsAlerter(); console-setNext(std::move(file)); console-setNext(std::move(email)); console-setNext(std::move(sms)); return console; }4. 性能优化与陷阱规避4.1 内存管理策略智能指针选择共享所有权用shared_ptr独占所有权用unique_ptr原始指针仅用于非拥有引用循环引用防范// 错误示例会导致内存泄漏 class Handler { std::shared_ptrHandler next_; // 强引用 public: void setNext(std::shared_ptrHandler next) { next_ next; next_-prev_ shared_from_this(); // 循环引用 } }; // 正确做法使用weak_ptr打破循环 class SafeHandler : public std::enable_shared_from_thisSafeHandler { std::weak_ptrSafeHandler next_; public: void setNext(std::shared_ptrSafeHandler next) { next_ next; } };4.2 线程安全实现多线程环境下的安全处理class ThreadSafeHandler { std::mutex mtx_; std::unique_ptrHandler next_; public: void setNext(std::unique_ptrHandler next) { std::lock_guardstd::mutex lock(mtx_); next_ std::move(next); } void handleRequest(const Request req) { std::unique_ptrHandler local_next; { std::lock_guardstd::mutex lock(mtx_); local_next std::move(next_); } if (local_next) { local_next-handleRequest(req); } } };4.3 常见陷阱及解决方案链断裂问题现象忘记设置next指针导致请求丢失解决采用Builder模式确保链完整性class HandlerBuilder { std::vectorstd::shared_ptrHandler handlers_; public: HandlerBuilder addHandler(std::shared_ptrHandler h) { if (!handlers_.empty()) { handlers_.back()-setNext(h); } handlers_.push_back(h); return *this; } std::shared_ptrHandler build() { return handlers_.front(); } };性能热点长链遍历导致延迟优化方案引入短路机制void handleRequest(const Request req) { if (canHandle(req)) { // 处理并终止传递 process(req); return; } if (next_) { next_-handleRequest(req); } }5. 模式变体与扩展应用5.1 中断式责任链允许处理者中断传递流程class InterruptibleHandler { public: enum class Result { PROCESSED, PASS_THROUGH, ABORT }; virtual Result handle(Request req) { if (canHandle(req)) { return process(req) ? Result::PROCESSED : Result::ABORT; } return Result::PASS_THROUGH; } }; void processChain(Request req) { for (auto handler : chain_) { auto res handler-handle(req); if (res ! Result::PASS_THROUGH) { return; // 中断传递 } } }5.2 异步责任链适用于IO密集型场景class AsyncHandler { boost::asio::io_context io_; std::unique_ptrAsyncHandler next_; public: void asyncHandle(std::shared_ptrRequest req) { post(io_, [this, req] { if (shouldHandle(*req)) { process(*req); } if (next_) { next_-asyncHandle(req); } }); } };5.3 组合模式结合构建树形处理结构class CompositeHandler : public Handler { std::vectorstd::unique_ptrHandler children_; public: void addHandler(std::unique_ptrHandler h) { children_.push_back(std::move(h)); } void handleRequest(const Request req) override { for (auto child : children_) { child-handleRequest(req); if (req.handled()) break; } } };在实际项目中我经常将职责链模式与策略模式结合使用。比如在电商订单处理系统中每个处理节点可以根据订单类型动态选择处理策略这种组合既保持了处理流程的清晰性又获得了策略选择的灵活性。一个经验之谈是当发现代码中出现大量条件判断语句特别是switch-case结构来处理不同情况时就应该考虑是否可以用职责链模式来重构了。
返回列表