2023-7-11-第十六式职责链模式

简介: 2023-7-11-第十六式职责链模式

😉一、基础概念

责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,它允许多个对象按照顺序处理请求,而不需要显式指定接收者。每个处理对象都可以决定是否处理请求以及将请求传递给下一个对象。

在责任链模式中,通常有一个抽象处理器(Handler)作为基类,定义了处理请求的接口方法,并维护一个指向下一个处理器的引用。具体的处理器(Concrete Handler)继承抽象处理器,并实现自己的处理逻辑。每个处理器都能够根据自身的职责决定是否能够处理请求,如果可以,则进行处理,否则将请求传递给下一个处理器。

责任链模式的主要优点包括:

  • 解耦发送者和接收者:发送者无需知道处理请求的具体处理器,只需将请求传递给第一个处理器即可。
  • 可灵活添加或删除处理器:由于处理器之间通过引用链连接,因此可以方便地添加新的处理器或调整处理器的顺序,以满足不同的业务需求。
  • 支持动态组合:可以通过动态配置处理器的顺序和组合关系,实现不同的处理流程。

然而,责任链模式也存在一些注意事项:

  • 请求可能无法被处理:如果所有的处理器都无法处理某个请求,会导致请求没有得到处理,需要避免这种情况的发生。
  • 可能引起性能问题:由于请求会依次经过多个处理器,如果责任链过长或者处理器逻辑复杂,可能会影响性能。

总之,责任链模式非常适合处理具有多个处理环节且每个环节处理逻辑独立的场景,比如请求的处理流程是可变的、需要动态组合的情况下。


🐱‍🐉二、职责链模式实现

以下是一个简单的C++实现示例,展示了如何使用责任链模式:

#include <iostream>
// 抽象处理器
class Handler {
public:
    virtual void setNextHandler(Handler* next) = 0;
    virtual void handleRequest(int request) = 0;
};
// 具体处理器A
class ConcreteHandlerA : public Handler {
private:
    Handler* nextHandler;
public:
    void setNextHandler(Handler* next) override {
        nextHandler = next;
    }
    void handleRequest(int request) override {
        if (request <= 10) {
            std::cout << "ConcreteHandlerA 处理请求 " << request << std::endl;
        } else if (nextHandler != nullptr) {
            nextHandler->handleRequest(request);
        }
    }
};
// 具体处理器B
class ConcreteHandlerB : public Handler {
private:
    Handler* nextHandler;
public:
    void setNextHandler(Handler* next) override {
        nextHandler = next;
    }
    void handleRequest(int request) override {
        if (request > 10 && request <= 20) {
            std::cout << "ConcreteHandlerB 处理请求 " << request << std::endl;
        } else if (nextHandler != nullptr) {
            nextHandler->handleRequest(request);
        }
    }
};
// 具体处理器C
class ConcreteHandlerC : public Handler {
private:
    Handler* nextHandler;
public:
    void setNextHandler(Handler* next) override {
        nextHandler = next;
    }
    void handleRequest(int request) override {
        if (request > 20 && request <= 30) {
            std::cout << "ConcreteHandlerC 处理请求 " << request << std::endl;
        } else if (nextHandler != nullptr) {
            nextHandler->handleRequest(request);
        }
    }
};
int main() {
    // 创建具体处理器对象
    ConcreteHandlerA handlerA;
    ConcreteHandlerB handlerB;
    ConcreteHandlerC handlerC;
    // 设置处理器之间的关系
    handlerA.setNextHandler(&handlerB);
    handlerB.setNextHandler(&handlerC);
    // 发送请求
    handlerA.handleRequest(5);
    handlerA.handleRequest(15);
    handlerA.handleRequest(25);
    return 0;
}

在上述示例中,我们定义了三个具体的处理器(ConcreteHandlerAConcreteHandlerBConcreteHandlerC),它们分别处理不同范围的请求。每个处理器都实现了setNextHandler方法来设置下一个处理器,并实现了handleRequest方法来处理请求或将请求传递给下一个处理器。

main函数中,我们创建了具体处理器对象,并按照顺序设置处理器之间的关系。然后,我们通过调用第一个处理器的handleRequest方法发送请求,整个请求会依次经过处理器链进行处理,直到找到能够处理该请求的处理器,或者到达链的末尾。

运行代码,你将看到输出结果如下:

ConcreteHandlerA 处理请求 5
ConcreteHandlerB 处理请求 15
ConcreteHandlerC 处理请求 25

这个示例展示了职责链模式的基本使用方式。你可以根据具体场景和需求,扩展和定制处理器的逻辑,并设置不同的处理器顺序以满足业务要求。


🎉三、模块之间的关系

在责任链模式中,模块之间的关系可以分为以下几种角色和交互方式:

  1. 抽象处理器(Handler):
  • 定义了处理请求的接口方法。
  • 维护一个指向下一个处理器的引用。
  1. 具体处理器(Concrete Handler):
  • 继承自抽象处理器,并实现处理请求的具体逻辑。
  • 可以决定是否处理请求,如果无法处理,则将请求传递给下一个处理器。
  • 可以设置下一个处理器的引用,建立处理器链。
  1. 请求发送者(Client):
  • 创建处理器对象,并设置它们之间的关系,形成处理器链。
  • 将请求发送给第一个处理器来触发处理链的执行。
  1. 处理器链(Chain of Responsibility):
  • 由多个具体处理器组成的链状结构。
  • 每个处理器负责处理一部分请求,或将请求传递给下一个处理器。
  • 处理器链的顺序通常按照业务逻辑进行设置。

在责任链模式中,请求从发送者开始,经过处理器链的依次处理,直到找到能够处理该请求的处理器。处理器链的顺序是通过设置每个处理器的下一个处理器来建立的。处理器可以根据自身的职责决定是否能够处理请求,并可以选择将请求传递给下一个处理器。

通过这种方式,责任链模式实现了请求发送者和接收者之间的解耦,使得请求的处理流程可以动态调整和扩展。每个处理器都只需要关注自己的业务逻辑,而不需要知道整个处理流程的细节。

总之,责任链模式中的模块之间通过处理器链的方式相互连接,形成一条处理路径。处理器链的建立和处理器之间的交互,使得多个处理器能够协同工作来处理请求,提高系统的灵活性和可扩展性。


🐱‍🚀四、注意事项

在使用责任链模式时,需要注意以下几个事项:

  1. 避免形成循环链:在设置处理器之间的关系时,需要确保不会形成循环链,即一个处理器的下一个处理器不能再回到自身或者前面的处理器。否则,请求可能会陷入无限循环。
  2. 保证请求能够被处理:处理器链中至少应该有一个处理器能够处理请求,否则请求将无法得到处理。因此,在设计和配置处理器链时,需要确保每个请求都能够被正确地处理或传递给下一个处理器。
  3. 不要过度使用责任链:责任链模式适用于一系列相互独立且可变的处理环节,但并不是所有的场景都适合使用责任链模式。如果处理环节之间的耦合度很高,或者处理器之间的顺序和组合关系不常发生变化,那么使用责任链模式可能会增加系统复杂性,不利于维护和理解代码。
  4. 注意性能问题:由于请求经过多个处理器进行处理,如果责任链过长或者处理器逻辑复杂,可能会影响系统的性能。在实际使用中,需要根据具体情况进行评估和测试,以确保责任链模式的性能满足需求。
  5. 合理划分职责:每个处理器应该只关注自己的职责范围内的请求处理,不要将不相关的逻辑放在同一个处理器中。这有助于提高代码的可读性和可维护性。

总之,使用责任链模式时需要注意合理设计处理器链、避免循环链的出现,确保请求能够被正确处理或传递,以及关注性能问题和职责的划分。正确使用责任链模式可以提高系统的灵活性和可扩展性,但也需要根据具体情况进行评估和权衡。


🎂五、使用场景

职责链模式适用于以下场景:

  1. 处理流程具有多个环节:当业务操作需要经过一系列处理环节,每个环节可能由不同的处理器负责处理时,可以使用责任链模式。例如,订单处理系统中的订单审核、支付、发货等环节。
  2. 动态组合和调整处理流程:如果处理流程的组合和顺序需要根据不同情况进行动态调整,责任链模式可以提供灵活性。通过添加、删除或重新排列处理器,可以实现不同的处理流程。
  3. 解耦请求发送者和接收者:使用责任链模式可以解耦请求发送者和具体的处理器,使得发送者无需知道哪个处理器会处理请求。这样可以简化发送者的代码,且方便增加新的处理器。
  4. 多个对象可以处理同一请求:在某些情况下,一个请求可能被多个对象中的一个处理,而不是固定的某个对象。责任链模式允许多个对象按照顺序尝试处理请求,直到找到能够处理的对象。
  5. 避免请求的发送者与接收者之间的耦合:使用责任链模式可以降低请求发送者与接收者之间的耦合度。发送者只需将请求发送给第一个处理器,而不需要关心具体的处理器是谁,从而增加了系统的灵活性和可扩展性。

综上所述,职责链模式适用于处理具有多个环节且每个环节处理逻辑独立、处理流程需要动态组合或调整的场景。它能够提供灵活性、解耦请求发送者和接收者,并支持多个对象处理同一请求的情况。


🍳参考文献

🧊文章总结

提示:这里对文章进行总结:

   本文讲了关于职责链模式的知识。


目录
相关文章
|
6月前
|
设计模式 算法 前端开发
【面试题】什么是策略模式?用了策略模式之后,再也不用写那么多 if else 了,真香!
【面试题】什么是策略模式?用了策略模式之后,再也不用写那么多 if else 了,真香!
|
6月前
|
设计模式 算法
【设计模式】阿里终面:你觉得这个例子是策略模式吗?
【设计模式】阿里终面:你觉得这个例子是策略模式吗?
55 1
|
6月前
|
设计模式 Java
小谈设计模式(25)—职责链模式
小谈设计模式(25)—职责链模式
|
6月前
|
算法
犯错总结--工厂模式和策略模式傻傻没分清
犯错总结--工厂模式和策略模式傻傻没分清
60 0
犯错总结--工厂模式和策略模式傻傻没分清
|
6月前
|
设计模式 算法 Java
二十三种设计模式全面解析-当你的代码需要多种算法时,策略模式是你的救星!
二十三种设计模式全面解析-当你的代码需要多种算法时,策略模式是你的救星!
|
设计模式 数据安全/隐私保护
这才是责任链模式的优雅使用方式
首先创建一个实体类Member。
107 0
|
前端开发
前端学习笔记202306学习笔记第五十二天-职责链模式2
前端学习笔记202306学习笔记第五十二天-职责链模式2
36 0
|
前端开发
前端学习笔记202306学习笔记第五十二天-职责链模式4
前端学习笔记202306学习笔记第五十二天-职责链模式4
51 0
|
设计模式 调度 C++
2023-7-14-第十九式中介者模式
2023-7-14-第十九式中介者模式
70 0
|
设计模式 算法 C++
2023-7-20-第二十一式访问者模式
2023-7-20-第二十一式访问者模式
78 0