跳转到内容

C++ 责任链模式

来自代码酷

C++责任链模式[编辑 | 编辑源代码]

责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,允许你将请求沿着处理链传递,直到有一个处理者能够处理该请求。这种模式解耦了请求的发送者和接收者,允许多个对象都有机会处理请求。

介绍[编辑 | 编辑源代码]

责任链模式的核心思想是构建一个处理对象的链,每个处理对象包含对另一个处理对象的引用。当一个请求被发送到链中时,处理对象可以决定是否处理该请求,或者将其传递给链中的下一个处理对象。

在C++中,责任链模式通常通过指针或引用将处理者连接起来,每个处理者实现相同的接口或基类。

结构[编辑 | 编辑源代码]

责任链模式的主要组成部分包括:

  • Handler(处理者接口):定义一个处理请求的接口,通常包含一个指向下一个处理者的引用。
  • ConcreteHandler(具体处理者):实现处理请求的具体逻辑,决定是否处理请求或将其传递给下一个处理者。
  • Client(客户端):创建处理链并向链的头部发送请求。

以下是一个简单的类图表示:

classDiagram class Handler { +Handler* nextHandler +setNext(Handler* handler) +handleRequest(Request request) } class ConcreteHandlerA { +handleRequest(Request request) } class ConcreteHandlerB { +handleRequest(Request request) } class Client { -Handler* chain } Handler <|-- ConcreteHandlerA Handler <|-- ConcreteHandlerB Handler o-- Handler Client --> Handler

代码示例[编辑 | 编辑源代码]

以下是一个简单的C++实现,展示责任链模式的基本用法:

#include <iostream>
#include <string>

// 请求类
class Request {
public:
    std::string type;
    int value;
    Request(const std::string& t, int v) : type(t), value(v) {}
};

// 处理者接口
class Handler {
protected:
    Handler* nextHandler;
public:
    Handler() : nextHandler(nullptr) {}
    virtual ~Handler() = default;
    
    void setNext(Handler* handler) {
        nextHandler = handler;
    }
    
    virtual void handleRequest(const Request& req) = 0;
};

// 具体处理者A
class ConcreteHandlerA : public Handler {
public:
    void handleRequest(const Request& req) override {
        if (req.type == "TypeA") {
            std::cout << "ConcreteHandlerA 处理了类型为 " << req.type 
                      << " 的请求,值为 " << req.value << std::endl;
        } else if (nextHandler != nullptr) {
            nextHandler->handleRequest(req);
        } else {
            std::cout << "没有处理者能处理此请求" << std::endl;
        }
    }
};

// 具体处理者B
class ConcreteHandlerB : public Handler {
public:
    void handleRequest(const Request& req) override {
        if (req.type == "TypeB") {
            std::cout << "ConcreteHandlerB 处理了类型为 " << req.type 
                      << " 的请求,值为 " << req.value << std::endl;
        } else if (nextHandler != nullptr) {
            nextHandler->handleRequest(req);
        } else {
            std::cout << "没有处理者能处理此请求" << std::endl;
        }
    }
};

int main() {
    // 创建处理链
    Handler* handlerA = new ConcreteHandlerA();
    Handler* handlerB = new ConcreteHandlerB();
    handlerA->setNext(handlerB);
    
    // 创建请求
    Request req1("TypeA", 10);
    Request req2("TypeB", 20);
    Request req3("TypeC", 30);
    
    // 发送请求
    handlerA->handleRequest(req1);
    handlerA->handleRequest(req2);
    handlerA->handleRequest(req3);
    
    delete handlerA;
    delete handlerB;
    return 0;
}

输出结果:

ConcreteHandlerA 处理了类型为 TypeA 的请求,值为 10
ConcreteHandlerB 处理了类型为 TypeB 的请求,值为 20
没有处理者能处理此请求

实际应用场景[编辑 | 编辑源代码]

责任链模式在以下场景中特别有用:

1. 多级审批系统:例如公司中的请假审批流程,不同级别的领导有不同的审批权限。 2. 事件处理系统:GUI框架中,事件可能被多个处理器依次尝试处理。 3. 日志系统:不同级别的日志消息可能被不同处理器处理(控制台、文件、网络等)。 4. 异常处理:异常可以在调用栈中向上传递,直到被捕获。

多级审批示例[编辑 | 编辑源代码]

以下是一个简化的多级审批系统示例:

#include <iostream>
#include <string>

class ApprovalRequest {
public:
    std::string content;
    double amount;
    ApprovalRequest(const std::string& c, double a) : content(c), amount(a) {}
};

class Approver {
protected:
    Approver* nextApprover;
    std::string name;
    double approvalLimit;
public:
    Approver(const std::string& n, double limit) 
        : name(n), approvalLimit(limit), nextApprover(nullptr) {}
    
    void setNext(Approver* approver) {
        nextApprover = approver;
    }
    
    virtual void processRequest(const ApprovalRequest& req) {
        if (req.amount <= approvalLimit) {
            std::cout << name << " 批准了申请: " << req.content 
                      << " 金额: " << req.amount << std::endl;
        } else if (nextApprover != nullptr) {
            nextApprover->processRequest(req);
        } else {
            std::cout << "申请需要董事会批准: " << req.content 
                      << " 金额: " << req.amount << std::endl;
        }
    }
};

int main() {
    // 创建审批链
    Approver* manager = new Approver("部门经理", 1000);
    Approver* director = new Approver("总监", 5000);
    Approver* vp = new Approver("副总裁", 10000);
    
    manager->setNext(director);
    director->setNext(vp);
    
    // 创建审批请求
    ApprovalRequest req1("购买办公用品", 800);
    ApprovalRequest req2("团队建设活动", 4500);
    ApprovalRequest req3("新服务器采购", 15000);
    
    // 处理请求
    manager->processRequest(req1);
    manager->processRequest(req2);
    manager->processRequest(req3);
    
    delete manager;
    delete director;
    delete vp;
    return 0;
}

输出结果:

部门经理 批准了申请: 购买办公用品 金额: 800
总监 批准了申请: 团队建设活动 金额: 4500
申请需要董事会批准: 新服务器采购 金额: 15000

优缺点[编辑 | 编辑源代码]

优点:

  • 降低耦合度:请求发送者不需要知道哪个对象会处理请求
  • 动态添加或修改处理链
  • 可以灵活地分配责任给多个对象

缺点:

  • 请求可能未被处理(如果没有合适的处理者)
  • 可能影响性能,特别是在长链中
  • 调试可能较复杂

与其他模式的关系[编辑 | 编辑源代码]

  • 责任链模式常与组合模式一起使用,此时处理者的父类可以同时作为组合模式的组件接口。
  • 责任链模式与命令模式可以结合使用,命令对象可以作为请求在链中传递。
  • 责任链模式与装饰器模式结构相似,但目的不同:装饰器模式是动态添加功能,而责任链模式是传递请求直到被处理。

总结[编辑 | 编辑源代码]

责任链模式是一种强大的行为设计模式,特别适合处理需要多个对象按顺序处理请求的场景。通过将处理者组织成链,我们可以实现灵活的请求处理机制,同时保持代码的低耦合性。在C++中,通过指针或引用实现处理者之间的连接,可以高效地构建处理链。