C++实现设计模式---职责链模式 (Chain of Responsibility)

职责链模式 (Chain of Responsibility)

职责链模式 是一种行为型设计模式,它允许多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合。这些对象通过形成一条链,沿着这条链传递请求,直到有对象处理它为止。


意图

  • 通过将请求的发送者与接收者解耦,动态地决定由哪个对象来处理请求。
  • 使多个对象有机会处理请求,而不是由固定的对象处理。

使用场景

  1. 请求的处理者不确定
    • 在运行时,可能需要多个对象来处理请求,但具体的处理者在编译时无法确定。
  2. 需要动态组合请求处理的责任链
    • 希望将多个处理者按顺序动态排列。
  3. 减少耦合
    • 将请求的发送者和处理者解耦。

参与者角色

  1. 处理者接口 (Handler)
    • 定义处理请求的方法,并保存对下一个处理者的引用。
  2. 具体处理者 (ConcreteHandler)
    • 实现处理者接口,处理请求或将请求传递给下一个处理者。
  3. 客户端 (Client)
    • 创建责任链,并向责任链中的第一个处理者发送请求。

示例代码

以下代码展示了职责链模式的实现,用于模拟用户请求的权限校验。系统中有三种责任:身份验证、权限验证和业务处理。

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

// 处理者接口
class Handler {
protected:
    std::shared_ptr<Handler> nextHandler; // 下一个处理者

public:
    virtual ~Handler() = default;

    // 设置下一个处理者
    void setNext(std::shared_ptr<Handler> next) {
        nextHandler = std::move(next);
    }

    // 处理请求的接口
    virtual void handleRequest(const std::string& request) {
        if (nextHandler) {
            nextHandler->handleRequest(request); // 将请求传递给下一个处理者
        }
    }
};

// 具体处理者:身份验证
class AuthHandler : public Handler {
public:
    void handleRequest(const std::string& request) override {
        if (request == "auth") {
            std::cout << "身份验证通过。
";
            if (nextHandler) {
                nextHandler->handleRequest(request); // 传递给下一个处理者
            }
        } else {
            std::cout << "身份验证失败。
";
        }
    }
};

// 具体处理者:权限验证
class PermissionHandler : public Handler {
public:
    void handleRequest(const std::string& request) override {
        if (request == "auth") {
            std::cout << "权限验证通过。
";
            if (nextHandler) {
                nextHandler->handleRequest(request); // 传递给下一个处理者
            }
        } else {
            std::cout << "权限验证失败。
";
        }
    }
};

// 具体处理者:业务处理
class BusinessHandler : public Handler {
public:
    void handleRequest(const std::string& request) override {
        if (request == "auth") {
            std::cout << "业务处理完成。
";
        } else {
            std::cout << "无法进行业务处理。
";
        }
    }
};

// 客户端代码
int main() {
    // 创建处理者
    auto authHandler = std::make_shared<AuthHandler>();
    auto permissionHandler = std::make_shared<PermissionHandler>();
    auto businessHandler = std::make_shared<BusinessHandler>();

    // 构建责任链
    authHandler->setNext(permissionHandler);
    permissionHandler->setNext(businessHandler);

    // 发送请求
    std::cout << "发送请求:auth
";
    authHandler->handleRequest("auth");

    std::cout << "
发送请求:invalid
";
    authHandler->handleRequest("invalid");

    return 0;
}

代码解析

1. 处理者接口 (Handler)
  • 定义了处理请求的接口 handleRequest,并包含对下一个处理者的引用。
  • 通过 setNext 方法设置链中的下一个处理者。
cpp 复制代码
class Handler {
protected:
    std::shared_ptr<Handler> nextHandler; // 下一个处理者
public:
    virtual ~Handler() = default;
    void setNext(std::shared_ptr<Handler> next) {
        nextHandler = std::move(next);
    }
    virtual void handleRequest(const std::string& request) {
        if (nextHandler) {
            nextHandler->handleRequest(request); // 将请求传递给下一个处理者
        }
    }
};
2. 具体处理者 (AuthHandler, PermissionHandler, BusinessHandler)
  • AuthHandler
    • 验证请求是否通过身份认证。
  • PermissionHandler
    • 验证请求是否有权限。
  • BusinessHandler
    • 完成实际的业务逻辑处理。
cpp 复制代码
class AuthHandler : public Handler {
public:
    void handleRequest(const std::string& request) override {
        if (request == "auth") {
            std::cout << "身份验证通过。
";
            if (nextHandler) {
                nextHandler->handleRequest(request);
            }
        } else {
            std::cout << "身份验证失败。
";
        }
    }
};
3. 客户端代码
  • 客户端创建责任链的各个处理者,并将它们按顺序连接。
  • 最后,将请求发送到链中的第一个处理者。
cpp 复制代码
int main() {
    auto authHandler = std::make_shared<AuthHandler>();
    auto permissionHandler = std::make_shared<PermissionHandler>();
    auto businessHandler = std::make_shared<BusinessHandler>();

    authHandler->setNext(permissionHandler);
    permissionHandler->setNext(businessHandler);

    authHandler->handleRequest("auth");
}

优缺点

优点
  1. 请求处理灵活
    • 可以根据需要动态地改变责任链的结构。
  2. 解耦请求发送者与处理者
    • 请求发送者不需要知道具体的处理者。
  3. 职责分离
    • 每个处理者只关注自己的职责。
缺点
  1. 请求可能未被处理
    • 如果责任链中没有处理者能处理请求,请求可能会被丢弃。
  2. 调试难度增加
    • 链的结构动态变化,可能导致调试困难。

适用场景

  1. 多个对象可以处理同一个请求
    • 如任务的审批流程。
  2. 需要动态组合请求处理逻辑
    • 可以灵活调整处理者的顺序。
  3. 解耦请求的发送者与接收者
    • 请求发送者不需要直接调用处理者。

总结

职责链模式通过将请求沿着处理者链传递,实现了请求的动态处理。它特别适用于需要动态组合请求处理逻辑,或者需要解耦请求发送者和接收者的场景。

相关推荐
短剑重铸之日8 分钟前
《设计模式》第十一篇:总结
java·后端·设计模式·总结
艾莉丝努力练剑12 分钟前
【Linux:文件】Ext系列文件系统(初阶)
大数据·linux·运维·服务器·c++·人工智能·算法
Once_day28 分钟前
C++之《程序员自我修养》读书总结(1)
c语言·开发语言·c++·程序员自我修养
Trouvaille ~38 分钟前
【Linux】TCP Socket编程实战(一):API详解与单连接Echo Server
linux·运维·服务器·网络·c++·tcp/ip·socket
feasibility.1 小时前
AI 编程助手进阶指南:从 Claude Code 到 OpenCode 的工程化经验总结
人工智能·经验分享·设计模式·自动化·agi·skills·opencode
坚果派·白晓明1 小时前
在鸿蒙设备上快速验证由lycium工具快速交叉编译的C/C++三方库
c语言·c++·harmonyos·鸿蒙·编程语言·openharmony·三方库
小镇敲码人1 小时前
深入剖析华为CANN框架下的Ops-CV仓库:从入门到实战指南
c++·python·华为·cann
BD_Marathon1 小时前
七大设计原则介绍
设计模式
张张努力变强2 小时前
C++ STL string 类:常用接口 + auto + 范围 for全攻略,字符串操作效率拉满
开发语言·数据结构·c++·算法·stl
小镇敲码人2 小时前
探索CANN框架中TBE仓库:张量加速引擎的优化之道
c++·华为·acl·cann·ops-nn