Bootstrap

设计模式——责任链模式

一、定义与概念

  • 定义
    C++ 责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它将请求的发送者和接收者解耦,让多个对象都有机会处理这个请求。这些对象被连接成一条链,请求沿着这条链传递,直到有一个对象处理它为止。
  • 核心思想
    把请求的处理过程分解成多个独立的处理步骤,每个步骤由一个对象负责。这些对象形成一个链状结构,当一个请求到达时,从链的头部开始逐个传递,每个对象都可以决定是否处理这个请求,如果不处理则将请求传递给下一个对象。

二、结构和组成部分

抽象处理者(Handler)

  • 定义:
    这是责任链中所有处理者类的抽象基类,它定义了处理请求的接口和设置下一个处理者的方法。这个抽象类为具体处理者类提供了一个统一的模板。
  • 代码示例(简单的请求处理接口)
class Handler {
public:
    virtual void handleRequest(int request) = 0;
    virtual void setNextHandler(Handler* next) = 0;
    virtual ~Handler() {}
};

具体处理者(Concrete Handler)

  • 定义:
    具体处理者类继承自抽象处理者类,实现了处理请求的接口。每个具体处理者类都有自己的处理逻辑,用于判断是否处理某个特定的请求,如果不处理则将请求传递给下一个处理者(如果存在)。
  • 代码示例(三个不同处理范围的具体处理者类)
    处理者 A
class ConcreteHandlerA : public Handler {
private:
    Handler* nextHandler;

public:
    void handleRequest(int request) override {
        if (request < 10) {
            std::cout << "ConcreteHandlerA handled the request." << std::endl;
        } else if (nextHandler!= nullptr) {
            nextHandler->handleRequest(request);
        }
    }

    void setNextHandler(Handler* next) override {
        nextHandler = next;
    }
};

处理者 B

class ConcreteHandlerB : public Handler {
private:
    Handler* nextHandler;

public:
    void handleRequest(int request) override {
        if (request >= 10 && request < 20) {
            std::cout << "ConcreteHandlerB handled the request." << std::endl;
        } else if (nextHandler!= nullptr) {
            nextHandler->handleRequest(request);
        }
    }

    void setNextHandler(Handler* next) override {
        nextHandler = next;
    }
};

处理者 C

class ConcreteHandlerC : public Handler {
private:
    Handler* nextHandler;

public:
    void handleRequest(int request) override {
        if (request >= 20) {
            std::cout << "ConcreteHandlerC handled the request." << std::endl;
        } else if (nextHandler!= nullptr) {
            nextHandler->handleRequest(request);
        }
    }

    void setNextHandler(Handler* next) override {
        nextHandler = next;
    }
};

三、应用场景

事件处理系统

  • 解释:
    在事件处理系统中,多个事件处理器可以按照优先级或事件类型组成责任链。当一个事件发生时,它会在这个链中传递,直到找到合适的处理器来处理该事件。例如,在一个图形用户界面(GUI)系统中,鼠标点击事件可能首先被传递给窗口级别的事件处理器,如果窗口处理器不处理,则传递给控件级别的事件处理器,以此类推。
  • 示例:
    在一个简单的文本编辑软件中,用户的键盘输入事件可能先由基本的文本输入处理器处理,如果输入的是特殊字符(如快捷键),则可能需要传递给更高层次的命令处理器来执行相应的操作,如保存文件、复制粘贴等。

异常处理机制

  • 解释:
    责任链模式可以应用于异常处理,将异常按照类型或严重程度在不同的异常处理模块之间传递。每个异常处理模块负责处理特定类型或范围内的异常,如果当前模块不能处理,则将异常传递给下一个模块。
  • 示例:
    在一个多层架构的应用程序中,数据访问层可能产生数据库连接异常,业务逻辑层可能产生业务规则异常,表现层可能产生用户输入异常等。这些异常可以通过责任链模式进行处理,每个层都有自己的异常处理程序,从底层开始,异常依次向上传递,直到被合适的层处理。

工作流审批系统

  • 解释:
    在工作流审批系统中,一个申请或任务需要经过多个审批环节,每个审批环节可以看作是责任链中的一个处理者。申请从初始环节开始,沿着审批链依次传递,每个审批者根据自己的权限和规则决定是否批准申请,如果不批准则将申请传递给下一个审批者。
  • 示例:
    在企业的采购申请流程中,采购申请可能首先需要部门主管审批,如果金额较大还需要财务部门审批,最后可能需要高层领导审批。这些审批环节可以通过责任链模式来实现,每个审批者作为一个处理者,根据申请的金额、性质等因素决定是否批准申请。

四、优缺点

优点

  • 解耦请求发送者和接收者:
    使得请求的发送者不需要知道哪个具体的对象会处理请求,降低了两者之间的耦合度,提高了系统的灵活性和可维护性。
  • 动态组合处理流程:
    可以在运行时动态地改变处理链的结构,例如添加、删除或重新排列处理者,从而适应不同的业务需求。
  • 增强系统的可扩展性:
    方便添加新的处理者类来扩展系统的功能,只需要实现抽象处理者类并将其插入到处理链中即可。

缺点

  • 可能导致请求处理不及时:
    如果责任链过长,请求可能需要经过多个处理者才能得到处理,这可能会导致处理延迟,尤其是在对响应速度要求较高的系统中。
  • 调试困难:
    由于请求在多个对象之间传递,当出现问题时,很难确定是哪个处理者导致的问题,增加了调试的复杂性。
  • 性能开销:
    每个请求都需要在链上的多个对象之间传递,可能会带来一定的性能开销,特别是当处理者数量较多且处理逻辑复杂时。

责任链模式在处理具有多个处理步骤或不确定处理对象的请求时非常有效,但在使用时需要注意其缺点,合理设计处理链的结构和长度。

;