责任链模式的C++实现示例

核心思想

责任链模式是一种行为设计模式,允许多个对象都有机会处理请求,从而避免请求的发送者与接收者之间的耦合。请求沿着处理链传递,直到某个对象处理它为止。

解决的问题

解耦请求发送者与处理者 :请求的发送者无需知道具体由哪个对象处理请求。
​动态分配责任 :可以在运行时动态调整处理链,灵活添加或移除处理者。
​避免硬编码:避免将请求处理逻辑硬编码在某个类中,提高代码的可扩展性和可维护性。

使用场景

​多级审批流程 :如请假审批、报销审批等,每一级领导都可以处理或传递给上级。
​事件处理系统 :如 GUI 事件处理,事件可以沿着组件链传递,直到被处理。
​日志记录系统 :不同级别的日志消息可以被不同的日志处理器处理。
​过滤器链:如 HTTP 请求过滤器,每个过滤器可以处理请求或传递给下一个过滤器。

优点

​解耦 :请求发送者与处理者解耦,发送者无需知道具体处理者。
​动态性 :可以在运行时动态调整处理链。
​单一职责:每个处理者只关注自己的职责,符合单一职责原则。

缺点

​性能问题 :如果链过长,可能导致请求传递效率低下。
​不确定性:请求可能未被任何处理者处理,需要额外逻辑处理这种情况。

示例代码

以下是一个简单的责任链模式示例,模拟多级审批流程:

cpp 复制代码
#include <iostream>
#include <memory>
#include <string>

// 请求类
class Request {
public:
    Request(const std::string& content, int level) 
        : content_(content), level_(level) {}

    std::string getContent() const { return content_; }
    int getLevel() const { return level_; }

private:
    std::string content_; // 请求内容
    int level_;           // 请求级别
};

// 处理者基类
class Handler {
public:
    virtual ~Handler() = default;

    void setNext(std::shared_ptr<Handler> next) { next_ = next; }

    virtual void handleRequest(const Request& request) {
        if (next_) {
            next_->handleRequest(request); // 传递给下一个处理者
        } else {
            std::cout << "Request未被处理: " << request.getContent() << std::endl;
        }
    }

protected:
    std::shared_ptr<Handler> next_; // 下一个处理者
};

// 具体处理者:经理
class Manager : public Handler {
public:
    void handleRequest(const Request& request) override {
        if (request.getLevel() <= 1) {
            std::cout << "经理处理请求: " << request.getContent() << std::endl;
        } else {
            Handler::handleRequest(request); // 传递给下一个处理者
        }
    }
};

// 具体处理者:总监
class Director : public Handler {
public:
    void handleRequest(const Request& request) override {
        if (request.getLevel() <= 2) {
            std::cout << "总监处理请求: " << request.getContent() << std::endl;
        } else {
            Handler::handleRequest(request); // 传递给下一个处理者
        }
    }
};

// 具体处理者:CEO
class CEO : public Handler {
public:
    void handleRequest(const Request& request) override {
        if (request.getLevel() <= 3) {
            std::cout << "CEO处理请求: " << request.getContent() << std::endl;
        } else {
            Handler::handleRequest(request); // 传递给下一个处理者
        }
    }
};

int main() {
    // 创建处理链
    auto manager = std::make_shared<Manager>();
    auto director = std::make_shared<Director>();
    auto ceo = std::make_shared<CEO>();

    manager->setNext(director);
    director->setNext(ceo);

    // 创建请求
    Request request1("请假1天", 1);  // 经理处理
    Request request2("请假3天", 2);  // 总监处理
    Request request3("请假10天", 3); // CEO处理
    Request request4("请假30天", 4); // 未被处理

    // 处理请求
    manager->handleRequest(request1);
    manager->handleRequest(request2);
    manager->handleRequest(request3);
    manager->handleRequest(request4);

    return 0;
}

输出结果

bash 复制代码
经理处理请求: 请假1天
总监处理请求: 请假3天
CEO处理请求: 请假10天
Request未被处理: 请假30天

代码解析

Request 类 :封装请求内容和级别。

Handler 基类 :定义处理请求的接口,并持有下一个处理者的指针。
​具体处理者 Manager、Director、CEO ​:实现自己的处理逻辑,若无法处理则传递给下一个处理者。
​处理链:通过 setNext 方法动态构建处理链。

相关推荐
昕冉32 分钟前
Axure9中继器多数据实现分页
设计模式·axure·设计
昕冉34 分钟前
Axure9中继器实现数据排序
设计模式·axure·设计
拾光拾趣录41 分钟前
前端设计模式初探
设计模式
范纹杉想快点毕业44 分钟前
Qt、C++自定义按钮、组件、事件编程开发练习,万字实战解析!!
java·c语言·开发语言·c++·git·qt·github
恰薯条的屑海鸥1 小时前
零基础学前端-传统前端开发(第四期-JS基础)
开发语言·前端·javascript·javascript基础·前端入门·javascript教程
m0_619731191 小时前
C语言之内存对齐
c语言·开发语言
于本淡1 小时前
一篇文章快速学会CSS
开发语言·前端·css·数据结构·html·github
Allen Bright1 小时前
【JS-4.3-鼠标常用事件】深入理解DOM鼠标事件:全面指南与最佳实践
开发语言·javascript
让我们一起加油好吗1 小时前
【基础算法】贪心 (一) :简单贪心
c++·算法·贪心算法·stl·洛谷·牛客
真的想上岸啊2 小时前
学习C++、QT---03(C++的输入输出、C++的基本数据类型介绍)
开发语言·c++·学习