
1. 职责链模式基础回顾在深入探讨变体之前我们需要先明确经典职责链模式的核心概念。职责链模式Chain of Responsibility是一种行为设计模式它允许你将请求沿着处理者链进行传递直到有一个处理者能够处理它为止。这种模式最典型的应用场景是事件处理系统比如图形界面中的事件冒泡机制。当用户点击一个按钮时点击事件会先传递给按钮本身如果按钮不处理则会传递给它的父容器依此类推直到有对象处理这个事件或者到达顶层对象。经典实现通常包含以下核心组件Handler抽象处理者定义处理请求的接口通常包含一个指向下一个处理者的引用ConcreteHandler具体处理者实现具体的处理逻辑能够处理请求则处理否则传递给下一个Client客户端创建处理链并向链头的处理者提交请求一个最简单的C实现骨架如下class Handler { public: virtual ~Handler() {} void setNext(Handler* next) { next_ next; } virtual void handleRequest(const Request req) { if (next_) next_-handleRequest(req); } private: Handler* next_ nullptr; }; class ConcreteHandlerA : public Handler { public: void handleRequest(const Request req) override { if (canHandle(req)) { // 处理请求 } else { Handler::handleRequest(req); // 传递给下一个 } } };2. 职责链模式的常见变体2.1 中断式职责链经典实现中即使某个处理者已经处理了请求请求仍然会继续传递。中断式变体则会在第一个能够处理请求的处理者处停止传递。这种变体更接近现实世界中的审批流程 - 一旦某个领导批准了申请就不需要再向上级请示。实现关键在于修改handleRequest的返回值class Handler { public: bool handleRequest(const Request req) { if (canHandle(req)) { process(req); return true; } return next_ ? next_-handleRequest(req) : false; } };这种变体在Web中间件链中很常见比如身份验证中间件一旦验证失败就会中断请求处理流程。2.2 功能组合链这种变体允许每个处理者对请求进行部分处理然后将修改后的请求传递给下一个处理者。它类似于Unix管道每个处理器都对数据流进行某种转换。实现示例class Filter { public: virtual std::string apply(const std::string input) 0; }; class UpperCaseFilter : public Filter { public: std::string apply(const std::string input) override { std::string result input; std::transform(result.begin(), result.end(), result.begin(), ::toupper); return result; } }; // 使用方式 std::string result filter3-apply( filter2-apply( filter1-apply(input)));这种模式在数据处理流水线中非常有用比如图像处理滤镜链、编译器优化pass等。2.3 动态职责链经典职责链通常在编译时就已经确定而动态职责链允许在运行时动态修改处理者链。这为系统提供了更大的灵活性。实现要点使用std::list或std::vector存储处理者提供addHandler/removeHandler方法按顺序调用每个处理者示例代码class DynamicHandler { public: void addHandler(Handler* h) { handlers_.push_back(h); } void removeHandler(Handler* h) { handlers_.remove(h); } void handleRequest(const Request req) { for (auto* h : handlers_) { if (h-handleRequest(req)) break; } } private: std::listHandler* handlers_; };这种变体在插件系统中很常见插件可以在运行时被加载和卸载相应地修改处理链。3. 高级变体与模式组合3.1 模板方法职责链通过将模板方法模式与职责链结合我们可以为处理流程提供更结构化的控制。抽象基类定义处理框架具体子类实现特定步骤。class TemplateHandler { public: void handle(const Request req) { if (!preHandle(req)) return; bool handled process(req); postHandle(req, handled); if (!handled next_) next_-handle(req); } protected: virtual bool preHandle(const Request req) { return true; } virtual bool process(const Request req) 0; virtual void postHandle(const Request req, bool handled) {} };这种组合在Web框架中很常见比如Spring MVC的HandlerInterceptor。3.2 责任树模式当简单的线性链不足以表达复杂的处理逻辑时我们可以将链扩展为树形结构。每个处理者可能有多个后继形成处理树。实现要点处理者维护一个子处理者列表而非单个next_请求可以广播给所有子节点或按特定策略选择可能需要引入访问者模式来遍历树示例场景游戏中的伤害计算伤害可能需要同时传递给装备、buff、技能等多个系统进行处理。3.3 异步职责链传统职责链是同步的但在高并发系统中我们可能需要异步处理链。这种变体通常结合Promise/Future模式实现。class AsyncHandler { public: std::futureResponse handleAsync(const Request req) { return std::async([this, req] { auto resp process(req); if (!resp.isFinal() next_) { auto nextResp next_-handleAsync(req).get(); resp.merge(nextResp); } return resp; }); } };这种变体在微服务架构中很常见特别是需要组合多个服务结果的场景。4. C特定实现技巧4.1 智能指针管理链在现代C中我们可以用智能指针来管理处理者生命周期避免内存泄漏class Handler : public std::enable_shared_from_thisHandler { public: void setNext(std::shared_ptrHandler next) { next_ next; } protected: std::shared_ptrHandler next_; }; auto h1 std::make_sharedConcreteHandlerA(); auto h2 std::make_sharedConcreteHandlerB(); h1-setNext(h2);4.2 使用lambda简化处理者对于简单处理逻辑可以使用std::function替代完整类using HandlerFunc std::functionbool(const Request); class LambdaChain { public: template typename F void addHandler(F f) { handlers_.emplace_back(std::forwardF(f)); } bool handle(const Request req) { for (const auto h : handlers_) { if (h(req)) return true; } return false; } private: std::vectorHandlerFunc handlers_; };4.3 编译期职责链通过模板元编程我们可以在编译期构建处理链template typename... Handlers class CompileTimeChain; template typename Head, typename... Tail class CompileTimeChainHead, Tail... : private Head, private CompileTimeChainTail... { public: void handle(const Request req) { if (Head::process(req)) return; CompileTimeChainTail...::handle(req); } }; template class CompileTimeChain { public: void handle(const Request) {} };这种技术可以用在性能敏感的场合消除运行时开销。5. 性能优化与线程安全5.1 缓存处理者能力如果判断处理者能否处理请求的开销很大可以缓存结果class CachingHandler : public Handler { public: void handleRequest(const Request req) override { auto it cache_.find(req.type()); if (it cache_.end()) { bool canHandle canHandleRequest(req); cache_[req.type()] canHandle; if (canHandle) { process(req); return; } } else if (it-second) { process(req); return; } Handler::handleRequest(req); } private: std::unordered_mapRequestType, bool cache_; };5.2 并行处理链对于无状态且独立的处理者可以并行处理class ParallelChain { public: void handle(const Request req) { std::vectorstd::futurevoid futures; for (auto h : handlers_) { futures.push_back(std::async(std::launch::async, [h, req] { h-handle(req); })); } for (auto f : futures) f.wait(); } };5.3 线程安全实现多线程环境下使用职责链需要注意同步class ThreadSafeHandler { public: void addHandler(std::shared_ptrHandler h) { std::lock_guardstd::mutex lock(mutex_); handlers_.push_back(h); } void handleRequest(const Request req) { std::vectorstd::shared_ptrHandler localCopy; { std::lock_guardstd::mutex lock(mutex_); localCopy handlers_; } for (auto h : localCopy) { if (h-handleRequest(req)) break; } } private: std::vectorstd::shared_ptrHandler handlers_; std::mutex mutex_; };6. 实际应用案例分析6.1 游戏引擎中的输入处理现代游戏引擎通常使用职责链模式处理输入事件。例如class InputHandler { public: virtual bool handleInput(const InputEvent event) 0; }; // UI层优先处理 class UIInputHandler : public InputHandler { bool handleInput(const InputEvent event) override { if (isPointInUI(event.position())) { // 处理UI交互 return true; } return false; } }; // 玩家角色处理 class PlayerInputHandler : public InputHandler { bool handleInput(const InputEvent event) override { if (event.type() InputType::Movement) { // 处理移动 return true; } return false; } }; // 构建处理链 auto chain std::make_sharedInputProcessor(); chain-addHandler(std::make_sharedUIInputHandler()); chain-addHandler(std::make_sharedPlayerInputHandler());这种架构允许灵活地插入新的输入处理逻辑比如暂停菜单、调试控制台等。6.2 网络协议栈实现网络协议栈是职责链模式的经典应用场景class ProtocolLayer { public: void setUpperLayer(ProtocolLayer* upper) { upper_ upper; } void setLowerLayer(ProtocolLayer* lower) { lower_ lower; } virtual void send(Packet pkt) { if (lower_) lower_-send(pkt); } virtual void receive(Packet pkt) { if (upper_) upper_-receive(pkt); } protected: ProtocolLayer* upper_ nullptr; ProtocolLayer* lower_ nullptr; }; class IPLayer : public ProtocolLayer { void send(Packet pkt) override { // 添加IP头 ProtocolLayer::send(pkt); } void receive(Packet pkt) override { // 解析IP头 ProtocolLayer::receive(pkt); } };6.3 业务规则引擎在企业应用中复杂的业务规则可以使用职责链模式组织class DiscountRule { public: virtual double apply(double originalPrice, const User user) 0; }; class VIPDiscount : public DiscountRule { double apply(double price, const User user) override { if (user.isVIP()) { return price * 0.9; } return price; } }; class CouponDiscount : public DiscountRule { double apply(double price, const User user) override { if (user.hasCoupon()) { return price - 50; } return price; } }; class DiscountCalculator { public: double calculate(double price, const User user) { double result price; for (auto rule : rules_) { result rule-apply(result, user); } return result; } private: std::vectorstd::unique_ptrDiscountRule rules_; };这种架构使得添加新的折扣规则变得非常简单且不会影响现有代码。