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

C++软件设计模式之责任链模式

责任链模式的动机与意图

动机:
在软件开发中,经常会遇到需要处理一系列请求或事件的情况。这些请求可能需要经过多个处理对象,每个对象根据其职责决定是否处理请求或将其传递给下一个对象。责任链模式(Chain of Responsibility Pattern)提供了一种将请求的发送者和接收者解耦的方式,允许多个对象都有机会处理请求,从而避免了请求发送者与接收者之间的紧密耦合。

意图:
责任链模式的意图是使多个对象都有机会处理请求,从而避免请求的发送者与接收者之间的耦合。将这些对象连成一条链,并沿着这条链传递请求,直到有对象处理它为止。

适用场合

  1. 多个对象可以处理同一请求,但具体由哪个对象处理在运行时确定。
  2. 需要在不明确指定接收者的情况下,向多个对象中的一个提交请求。
  3. 需要动态指定一组对象处理请求,例如在运行时动态调整处理链。

责任链模式的变体

  1. 纯责任链模式:

    • 每个处理者要么处理请求,要么将请求传递给下一个处理者,但不能同时进行。
    • 这种模式通常用于严格的链式处理,例如审批流程。
  2. 不纯责任链模式:

    • 处理者可以部分处理请求,然后将请求传递给下一个处理者。
    • 这种模式允许处理者在处理请求的同时,继续传递请求,适用于需要多个处理者共同完成任务的场景。
  3. 带中断的责任链模式:

    • 处理者可以在处理请求后决定是否中断链的传递。
    • 这种模式适用于某些情况下,一旦请求被处理,就不需要继续传递的场景。
  4. 带优先级的责任链模式:

    • 处理者根据优先级决定是否处理请求,优先级高的处理者先处理请求。
    • 这种模式适用于需要根据优先级决定处理顺序的场景。

以下是基于责任链模式的不同变体的 C++ 代码示例。每个示例都展示了如何在 C++ 中实现责任链模式的不同形式。


1. 纯责任链模式

在纯责任链模式中,每个处理者要么处理请求,要么将请求传递给下一个处理者。处理者不会同时处理请求并传递请求。

#include <iostream>
#include <memory>

class Handler {
public:
    virtual ~Handler() = default;
    virtual void setNext(std::shared_ptr<Handler>) = 0;
    virtual void handle(const std::string& request) = 0;
};

class BaseHandler : public Handler {
protected:
    std::shared_ptr<Handler> nextHandler;

public:
    void setNext(std::shared_ptr<Handler> handler) override {
        nextHandler = handler;
    }

    void handle(const std::string& request) override {
        if (nextHandler) {
            nextHandler->handle(request);
        }
    }
};

class ConcreteHandlerA : public BaseHandler {
public:
    void handle(const std::string& request) override {
        if (request == "A") {
            std::cout << "ConcreteHandlerA handles request: " << request << std::endl;
        } else {
            BaseHandler::handle(request);
        }
    }
};

class ConcreteHandlerB : public BaseHandler {
public:
    void handle(const std::string& request) override {
        if (request == "B") {
            std::cout << "ConcreteHandlerB handles request: " << request << std::endl;
        } else {
            BaseHandler::handle(request);
        }
    }
};

int main() {
    auto handlerA = std::make_shared<ConcreteHandlerA>();
    auto handlerB = std::make_shared<ConcreteHandlerB>();

    handlerA->setNext(handlerB);

    handlerA->handle("B");  // ConcreteHandlerB handles request: B
    handlerA->handle("A");  // ConcreteHandlerA handles request: A
    handlerA->handle("C");  // No handler can process C

    return 0;
}


2. 不纯责任链模式

在不纯责任链模式中,处理者可以部分处理请求,然后将请求传递给下一个处理者。

#include <iostream>
#include <memory>

class Handler {
public:
    virtual ~Handler() = default;
    virtual void setNext(std::shared_ptr<Handler>) = 0;
    virtual void handle(const std::string& request) = 0;
};

class BaseHandler : public Handler {
protected:
    std::shared_ptr<Handler> nextHandler;

public:
    void setNext(std::shared_ptr<Handler> handler) override {
        nextHandler = handler;
    }

    void handle(const std::string& request) override {
        if (nextHandler) {
            nextHandler->handle(request);
        }
    }
};

class ConcreteHandlerA : public BaseHandler {
public:
    void handle(const std::string& request) override {
        if (request == "A") {
            std::cout << "ConcreteHandlerA handles request: " << request << std::endl;
        } else {
            std::cout << "ConcreteHandlerA partially processes request: " << request << std::endl;
            BaseHandler::handle(request);
        }
    }
};

class ConcreteHandlerB : public BaseHandler {
public:
    void handle(const std::string& request) override {
        if (request == "B") {
            std::cout << "ConcreteHandlerB handles request: " << request << std::endl;
        } else {
            std::cout << "ConcreteHandlerB partially processes request: " << request << std::endl;
            BaseHandler::handle(request);
        }
    }
};

int main() {
    auto handlerA = std::make_shared<ConcreteHandlerA>();
    auto handlerB = std::make_shared<ConcreteHandlerB>();

    handlerA->setNext(handlerB);

    handlerA->handle("B");  // ConcreteHandlerB handles request: B
    handlerA->handle("A");  // ConcreteHandlerA handles request: A
    handlerA->handle("C");  // ConcreteHandlerA partially processes request: C
                             // ConcreteHandlerB partially processes request: C

    return 0;
}


3. 带中断的责任链模式

在带中断的责任链模式中,处理者可以在处理请求后决定是否中断链的传递。

#include <iostream>
#include <memory>

class Handler {
public:
    virtual ~Handler() = default;
    virtual void setNext(std::shared_ptr<Handler>) = 0;
    virtual bool handle(const std::string& request) = 0;
};

class BaseHandler : public Handler {
protected:
    std::shared_ptr<Handler> nextHandler;

public:
    void setNext(std::shared_ptr<Handler> handler) override {
        nextHandler = handler;
    }

    bool handle(const std::string& request) override {
        if (nextHandler) {
            return nextHandler->handle(request);
        }
        return false;
    }
};

class ConcreteHandlerA : public BaseHandler {
public:
    bool handle(const std::string& request) override {
        if (request == "A") {
            std::cout << "ConcreteHandlerA handles request: " << request << std::endl;
            return true;  // 中断链式传递
        }
        return BaseHandler::handle(request);
    }
};

class ConcreteHandlerB : public BaseHandler {
public:
    bool handle(const std::string& request) override {
        if (request == "B") {
            std::cout << "ConcreteHandlerB handles request: " << request << std::endl;
            return true;  // 中断链式传递
        }
        return BaseHandler::handle(request);
    }
};

int main() {
    auto handlerA = std::make_shared<ConcreteHandlerA>();
    auto handlerB = std::make_shared<ConcreteHandlerB>();

    handlerA->setNext(handlerB);

    handlerA->handle("B");  // ConcreteHandlerB handles request: B
    handlerA->handle("A");  // ConcreteHandlerA handles request: A
    handlerA->handle("C");  // No handler can process C

    return 0;
}


4. 带优先级的责任链模式

在带优先级的责任链模式中,处理者根据优先级决定是否处理请求,优先级高的处理者先处理请求。

#include <iostream>
#include <memory>
#include <vector>
#include <algorithm>

class Handler {
public:
    virtual ~Handler() = default;
    virtual int getPriority() const = 0;
    virtual void handle(const std::string& request) = 0;
};

class BaseHandler : public Handler {
protected:
    int priority;

public:
    BaseHandler(int p) : priority(p) {}

    int getPriority() const override {
        return priority;
    }

    void handle(const std::string& request) override {
        // 默认不处理
    }
};

class ConcreteHandlerA : public BaseHandler {
public:
    ConcreteHandlerA(int p) : BaseHandler(p) {}

    void handle(const std::string& request) override {
        if (request == "A") {
            std::cout << "ConcreteHandlerA handles request: " << request << std::endl;
        }
    }
};

class ConcreteHandlerB : public BaseHandler {
public:
    ConcreteHandlerB(int p) : BaseHandler(p) {}

    void handle(const std::string& request) override {
        if (request == "B") {
            std::cout << "ConcreteHandlerB handles request: " << request << std::endl;
        }
    }
};

int main() {
    auto handlerA = std::make_shared<ConcreteHandlerA>(2);
    auto handlerB = std::make_shared<ConcreteHandlerB>(1);

    std::vector<std::shared_ptr<Handler>> handlers = {handlerA, handlerB};

    // 根据优先级排序
    std::sort(handlers.begin(), handlers.end(), [](const auto& h1, const auto& h2) {
        return h1->getPriority() > h2->getPriority();
    });

    for (const auto& handler : handlers) {
        handler->handle("B");  // ConcreteHandlerB handles request: B
        handler->handle("A");  // ConcreteHandlerA handles request: A
    }

    return 0;
}


总结

以上代码示例展示了责任链模式的四种不同变体:

  1. 纯责任链模式:处理者要么处理请求,要么传递请求。
  2. 不纯责任链模式:处理者可以部分处理请求并传递请求。
  3. 带中断的责任链模式:处理者可以中断链的传递。
  4. 带优先级的责任链模式:处理者根据优先级决定处理顺序。

这些变体可以根据具体需求灵活选择和实现,以满足不同场景下的功能需求。

基于责任链模式特点的软件架构模式

  1. 中间件架构:

    • 在Web开发中,中间件架构通常使用责任链模式来处理HTTP请求。每个中间件都可以对请求进行处理,然后决定是否将请求传递给下一个中间件。
    • 例如,Express.js中的中间件机制就是基于责任链模式实现的。
  2. 事件处理系统:

    • 在GUI编程中,事件处理系统通常使用责任链模式来处理用户事件。每个事件处理器可以处理事件,或者将事件传递给下一个处理器。
    • 例如,Java AWT/Swing中的事件处理机制就是基于责任链模式实现的。
  3. 工作流引擎:

    • 在工作流引擎中,责任链模式可以用于处理工作流中的各个步骤。每个步骤可以处理任务,或者将任务传递给下一个步骤。
    • 例如,Activiti等工作流引擎中的任务处理机制就是基于责任链模式实现的。
  4. 过滤器链:

    • 在Web应用中,过滤器链通常使用责任链模式来处理请求和响应。每个过滤器可以对请求或响应进行处理,然后将其传递给下一个过滤器。
    • 例如,Java Servlet中的过滤器机制就是基于责任链模式实现的。

总结

责任链模式通过将请求的发送者和接收者解耦,提供了一种灵活的方式来处理请求。它适用于多个对象可以处理同一请求的场景,并且可以通过不同的变体来满足不同的需求。基于责任链模式的特点,许多软件架构模式(如中间件架构、事件处理系统、工作流引擎和过滤器链)都采用了这种模式来实现灵活的处理机制。


http://www.kler.cn/a/463924.html

相关文章:

  • 25.1.3
  • 计算机网络•自顶向下方法:网络层介绍、路由器的组成
  • Pytorch的自动求导模块
  • 机器学习之模型评估——混淆矩阵,交叉验证与数据标准化
  • 数字孪生:物联+数据打造洞察世界新视角
  • 树莓派 Pico RP2040 教程点灯 双核编程案例
  • 【2024年-12月-18日-开源社区openEuler实践记录】openeuler - jenkins:开源项目持续集成与交付的幕后引擎
  • OpenCV调整图像亮度和对比度
  • 【NLP高频面题 - LLM训练篇】为什么要对LLM做有监督微调(SFT)?
  • 使用apisix+oidc+casdoor配置微服务网关
  • 第二讲 比特币的技术基础
  • GPU 进阶笔记(三):华为 NPU/GPU 演进
  • 【Spring MVC 异常处理机制】应对意外情况
  • Pandas-数据分组
  • Seata AT 模式两阶段过程原理解析【seata AT模式如何做到对业务的无侵入】
  • 前端:轮播图常见的几种实现方式
  • CSS 实现无限滚动的列表
  • Unity+Hybridclr发布WebGL记录
  • 自动化运维脚本的最佳设计模式与开发指南
  • css的长度单位有那些?
  • 工业软件发展添动力 深圳龙华与华为云再聚“首”
  • Redis--缓存穿透、击穿、雪崩以及预热问题(面试高频问题!)
  • pytorch将数据与模型都放到GPU上训练
  • OpenGL ES 04 图片数据是怎么写入到对应纹理单元的
  • chatwoot 开源客服系统搭建
  • 安卓入门五 BroadcastReceiver