C++职责链模式解析与多级审批系统实战

C++职责链模式解析与多级审批系统实战 1. 职责链模式的核心概念解析职责链模式Chain of Responsibility Pattern是行为型设计模式中的经典成员它通过构建一条处理请求的链条来解耦请求发送者和接收者。在C实战中这种模式特别适合处理需要多级审批、分级处理或动态指定处理者的场景。1.1 模式结构与组件典型的职责链模式包含以下核心组件Handler抽象处理者定义处理请求的接口通常包含处理方法和设置后继者的方法。在C中我们通常用抽象基类实现class Handler { public: virtual ~Handler() default; virtual void handleRequest(const Request req) 0; void setNext(Handler* next) { next_ next; } protected: Handler* next_ nullptr; };ConcreteHandler具体处理者实现具体的请求处理逻辑能够访问后继者对象。当自己无法处理时会将请求转发给后继者class ConcreteHandlerA : public Handler { public: void handleRequest(const Request req) override { if (canHandle(req)) { // 处理请求 } else if (next_) { next_-handleRequest(req); } } private: bool canHandle(const Request req) const { // 判断逻辑 } };Client客户端创建处理链并向链上的具体处理者对象提交请求。客户端通常不需要知道最终由哪个处理者实际处理了请求。1.2 模式运作机制职责链的核心运作流程可以概括为客户端创建处理者对象并组装成链客户端发起请求调用链首处理者每个处理者判断自己能否处理该请求能处理则处理并终止传递否则传递给后继者请求到达链尾仍未处理则可能被忽略或执行默认操作提示在实际C实现中建议为处理链设置一个终止条件避免请求在无限循环中传递。2. C实现职责链模式的关键技术点2.1 智能指针管理处理链在C中管理处理链的生命周期是个重要课题。原始指针容易导致内存泄漏推荐使用智能指针class Handler { public: virtual ~Handler() default; void setNext(std::shared_ptrHandler next) { next_ next; } protected: std::shared_ptrHandler next_; }; auto handler1 std::make_sharedConcreteHandlerA(); auto handler2 std::make_sharedConcreteHandlerB(); handler1-setNext(handler2);对于更复杂的链式结构可以考虑使用std::unique_ptr配合原始指针观察class Handler { public: virtual ~Handler() default; void setNext(std::unique_ptrHandler next) { next_ std::move(next); } protected: std::unique_ptrHandler next_; Handler* next() { return next_.get(); } };2.2 请求对象的封装设计请求对象的设计直接影响模式的灵活性。建议将请求封装为独立类class Request { public: enum class Type { TYPE_A, TYPE_B, TYPE_C }; explicit Request(Type type, const std::string data) : type_(type), data_(data) {} Type type() const { return type_; } const std::string data() const { return data_; } private: Type type_; std::string data_; };对于复杂场景可以采用变体设计using RequestData std::variantHttpRequest, FileRequest, ApiRequest; class Request { public: template typename T Request(const T data) : data_(data) {} template typename T bool holds() const { return std::holds_alternativeT(data_); } template typename T const T get() const { return std::getT(data_); } private: RequestData data_; };2.3 处理链的动态构建技术静态构建处理链的方式缺乏灵活性我们可以实现动态链构建class HandlerChain { public: template typename T, typename... Args void addHandler(Args... args) { auto handler std::make_sharedT(std::forwardArgs(args)...); if (!head_) { head_ handler; tail_ handler; } else { tail_-setNext(handler); tail_ handler; } } void handle(const Request req) { if (head_) { head_-handleRequest(req); } } private: std::shared_ptrHandler head_; std::shared_ptrHandler tail_; };使用示例HandlerChain chain; chain.addHandlerAuthHandler(); chain.addHandlerValidationHandler(); chain.addHandlerBusinessHandler(); chain.handle(request);3. 职责链模式的进阶应用技巧3.1 中断与继续机制标准职责链模式中一旦某个处理者处理了请求链就会终止。但有时我们需要更灵活的控制class Handler { public: enum class Result { HANDLED, // 已处理并终止 CONTINUE, // 未处理继续传递 HANDLED_CONT // 已处理但仍继续 }; void handleRequest(const Request req) { Result r handleImpl(req); if (r Result::CONTINUE next_) { next_-handleRequest(req); } } protected: virtual Result handleImpl(const Request req) 0; };3.2 责任链与模板方法的结合将模板方法模式与职责链结合可以统一处理流程class Handler { public: void handleRequest(const Request req) final { if (!preHandle(req)) return; bool handled doHandle(req); postHandle(req, handled); if (!handled next_) { next_-handleRequest(req); } } protected: virtual bool preHandle(const Request req) { return true; } virtual bool doHandle(const Request req) 0; virtual void postHandle(const Request req, bool handled) {} };3.3 异步职责链实现对于I/O密集型场景可以实现异步处理链class AsyncHandler : public std::enable_shared_from_thisAsyncHandler { public: using Callback std::functionvoid(const Response); void handleAsync(const Request req, Callback cb) { if (canHandle(req)) { asyncHandle(req, [cb, this](const Response resp) { cb(resp); }); } else if (next_) { next_-handleAsync(req, cb); } else { cb(Response::error(No handler found)); } } protected: virtual void asyncHandle(const Request req, Callback cb) 0; private: std::shared_ptrAsyncHandler next_; };4. 实战案例分析多级审批系统4.1 系统需求分析假设我们需要实现一个员工请假审批系统1天内直接主管审批3天内部门经理审批7天内分管副总审批超过7天CEO审批4.2 类结构设计class LeaveRequest { public: LeaveRequest(const std::string name, int days) : employee_(name), days_(days) {} const std::string employee() const { return employee_; } int days() const { return days_; } private: std::string employee_; int days_; }; class Approver : public Handler { public: explicit Approver(const std::string name) : name_(name) {} void handleRequest(const Request req) override { auto lr dynamic_castconst LeaveRequest(req); if (canApprove(lr)) { approve(lr); } else if (next_) { next_-handleRequest(req); } else { reject(lr); } } protected: virtual bool canApprove(const LeaveRequest lr) const 0; virtual void approve(const LeaveRequest lr) { std::cout name_ approved lr.employee() s lr.days() days leave\n; } virtual void reject(const LeaveRequest lr) { std::cout No one can approve lr.employee() s lr.days() days leave\n; } std::string name_; };4.3 具体审批者实现class Supervisor : public Approver { public: Supervisor() : Approver(Supervisor) {} protected: bool canApprove(const LeaveRequest lr) const override { return lr.days() 1; } }; class Manager : public Approver { public: Manager() : Approver(Manager) {} protected: bool canApprove(const LeaveRequest lr) const override { return lr.days() 3; } }; class DeputyGeneralManager : public Approver { public: DeputyGeneralManager() : Approver(Deputy GM) {} protected: bool canApprove(const LeaveRequest lr) const override { return lr.days() 7; } }; class CEO : public Approver { public: CEO() : Approver(CEO) {} protected: bool canApprove(const LeaveRequest lr) const override { return true; } };4.4 客户端使用示例void setupApprovalChain() { auto supervisor std::make_sharedSupervisor(); auto manager std::make_sharedManager(); auto deputyGM std::make_sharedDeputyGeneralManager(); auto ceo std::make_sharedCEO(); supervisor-setNext(manager); manager-setNext(deputyGM); deputyGM-setNext(ceo); return supervisor; } int main() { auto chain setupApprovalChain(); LeaveRequest req1(Alice, 1); chain-handleRequest(req1); LeaveRequest req2(Bob, 5); chain-handleRequest(req2); LeaveRequest req3(Charlie, 10); chain-handleRequest(req3); }5. 性能优化与陷阱规避5.1 处理链缓存技术频繁创建销毁处理链会影响性能可以采用对象池技术class HandlerPool { public: template typename T, typename... Args std::shared_ptrT acquire(Args... args) { std::lock_guardstd::mutex lock(mutex_); auto it std::find_if(pool_.begin(), pool_.end(), [](const auto ptr) { return !ptr-isInUse() dynamic_castT*(ptr.get()); }); if (it ! pool_.end()) { (*it)-reset(); return std::static_pointer_castT(*it); } auto handler std::make_sharedT(std::forwardArgs(args)...); pool_.push_back(handler); return handler; } private: std::vectorstd::shared_ptrHandler pool_; std::mutex mutex_; };5.2 循环引用检测处理链中的循环引用会导致内存泄漏和逻辑错误class Handler { public: void setNext(std::shared_ptrHandler next) { if (hasCycle(next)) { throw std::logic_error(Cycle detected in handler chain); } next_ next; } private: bool hasCycle(const std::shared_ptrHandler newNext) const { std::unordered_setconst Handler* visited; const Handler* current newNext.get(); while (current) { if (visited.count(current)) return true; visited.insert(current); current current-next_.get(); } return false; } };5.3 线程安全考量在多线程环境下使用职责链需要注意class ThreadSafeHandler : public Handler { public: void handleRequest(const Request req) override { std::lock_guardstd::mutex lock(mutex_); if (canHandle(req)) { // 处理请求 } else if (next_) { next_-handleRequest(req); } } protected: virtual bool canHandle(const Request req) 0; private: std::mutex mutex_; };6. 模式变体与替代方案6.1 拦截器链模式类似于职责链但每个拦截器都能处理请求和响应class Interceptor { public: virtual ~Interceptor() default; virtual void intercept(Request req, Response res, const std::functionvoid() next) 0; }; class InterceptorChain { public: void addInterceptor(std::shared_ptrInterceptor interceptor) { interceptors_.push_back(interceptor); } void execute(Request req, Response res) { execute(0, req, res); } private: void execute(size_t index, Request req, Response res) { if (index interceptors_.size()) return; interceptors_[index]-intercept(req, res, [this, index, req, res]() { execute(index 1, req, res); }); } std::vectorstd::shared_ptrInterceptor interceptors_; };6.2 管道-过滤器模式适用于数据处理流水线场景class Filter { public: virtual ~Filter() default; virtual Data process(const Data input) 0; }; class Pipeline { public: void addFilter(std::unique_ptrFilter filter) { filters_.push_back(std::move(filter)); } Data execute(const Data input) { Data result input; for (auto filter : filters_) { result filter-process(result); } return result; } private: std::vectorstd::unique_ptrFilter filters_; };6.3 与命令模式的结合将每个处理者实现为命令对象class Command { public: virtual ~Command() default; virtual bool execute(const Request req) 0; }; class CommandChain { public: void addCommand(std::unique_ptrCommand cmd) { commands_.push_back(std::move(cmd)); } void execute(const Request req) { for (auto cmd : commands_) { if (cmd-execute(req)) { return; } } } private: std::vectorstd::unique_ptrCommand commands_; };7. 测试策略与调试技巧7.1 单元测试设计要点测试处理链时需要关注单个处理者的行为处理链的顺序正确性请求传递逻辑边界条件处理示例测试用例TEST(HandlerChainTest, ShouldPassRequestDownTheChain) { auto handler1 std::make_sharedMockHandler(); auto handler2 std::make_sharedMockHandler(); handler1-setNext(handler2); Request req(test); EXPECT_CALL(*handler1, canHandle(req)) .WillOnce(Return(false)); EXPECT_CALL(*handler2, canHandle(req)) .WillOnce(Return(true)); handler1-handleRequest(req); }7.2 调试日志增强在处理链中添加调试日志class LoggingHandler : public Handler { public: explicit LoggingHandler(std::shared_ptrHandler handler, const std::string name) : handler_(handler), name_(name) {} void handleRequest(const Request req) override { std::cout Entering handler: name_ \n; handler_-handleRequest(req); std::cout Leaving handler: name_ \n; } private: std::shared_ptrHandler handler_; std::string name_; };7.3 可视化追踪工具实现请求追踪功能class TraceableRequest : public Request { public: TraceableRequest(const Request req) : Request(req) {} void addTrace(const std::string handler) { trace_.push_back(handler); } const std::vectorstd::string trace() const { return trace_; } }; class TracingHandler : public Handler { public: void handleRequest(const Request req) override { auto traceReq dynamic_castTraceableRequest(req); traceReq.addTrace(typeid(*this).name()); if (canHandle(req)) { handleImpl(req); } else if (next_) { next_-handleRequest(req); } } };