设计模式之责任链模式

面向对象设计原则

接口隔离原则面向对象设计之接口隔离原则-CSDN博客
设计模式

工厂模式设计模式之工厂模式-CSDN博客

迭代器模式设计模式之迭代器模式-CSDN博客

适配器模式设计模式之适配器模式-CSDN博客

过滤器模式设计模式之过滤器模式-CSDN博客

单例模式设计模式之单例模式-CSDN博客

观察者模式设计模式之观察者模式-CSDN博客

空对象模式设计模式之空对象模式-CSDN博客

桥接模式设计模式之桥接模式-CSDN博客

策略模式设计模式之策略模式-CSDN博客

责任链模式设计模式之责任链模式-CSDN博客

目录

1.概述

2.结构

3.实现

4.总结


1.概述

责任链模式(Chain of Responsibility Pattern)是一种行为性设计模式;它为请求创建了一个接收者对象的链,允许你将请求沿着处理者链进行发送。 收到请求后, 每个处理者均可对请求进行处理, 或将其传递给链上的下个处理者。这种处理方法类似包与包之间的调用的思路,只是其可以不在主程序中累赘的去申明一堆if else变量使得程序更加臃肿。在我的博客中就是利用责任链模式来消除多层if-else-if。

C++之多层 if-else-if 结构优化(二)_c++ 怎么优化很多if 的代码呢-CSDN博客

2.结构

责任链模式的重点是在"链"上,由一条链去处理相似的请求在链中决定谁来处理这个请求,并返回相应的结果,其通用类图如下图所示:

角色定义:

抽象处理者(Handler): 定义一个处理请求的接口,通常包含一个处理请求的方法(如 handleRequest)和一个指向下一个处理者的引用(后继者),一般这类情况class内部都是纯虚函数。
**具体处理者(ConcreteHandler):**实现了抽象处理者接口,负责处理请求。如果能够处理该请求,则直接处理;否则,将请求传递给下一个处理者;这样可以通过设计整个逻辑链避免混乱。
**客户端(Client):**创建处理者对象,并将它们连接成一条责任链。通常,客户端只需要将请求发送给责任链的第一个处理者,无需关心请求的具体处理过程。

3.实现

以公司的请假为例,普通员工请假小于等于2天只需要自己的组长同意,请假大于2天小于等于5天需要部门经理同意,大于5天小于10天需要公司总经理同意才行,大于10天的请不了。根据上面的需求,我们可以先抽象Handler,再定义组长、部门经理、总经理,代码如下:

cpp 复制代码
#include <iostream>
using namespace std;

//抽象处理者
class Handler
{
public:
    explicit Handler() { m_pNextHandler = NULL; }
    virtual ~Handler() {}

    //设置下一个处理者
    void setNextHandler(Handler *successor) { m_pNextHandler = successor; }

    //处理请求
    virtual void HandleRequest(int days) = 0;
protected:
    Handler *m_pNextHandler;  // 后继者
};


//组长
class CGroupLeader : public Handler
{
public:
    //处理请求
    void HandleRequest(int days) override
    {
        if (days <= 2)
        {
            cout << "我是组长,有权批准" << days << "天假,同意了!" << endl; 
        }
        else
        {
            m_pNextHandler->HandleRequest(days);
        }
    }
};

//部门经理
class CDeptManager : public Handler
{
public:
    //处理请求
    void HandleRequest(int days)  override
    {
        if (days <= 5)
        {
            cout << "我是部门经理,有权批准" << days << "天的假,同意了!" << endl;
        }
        else
        {
            m_pNextHandler->HandleRequest(days);
        }
    }
};

//总经理
class  CGeneralManager : public Handler
{
public:
    //处理请求
    void HandleRequest(int days) override
    {
        if (days <= 10)
        {
            cout << "我是总经理,最多让你请10天假,同意了!" << endl;
        }
        else
        {
            cout << "你请的假时间太长了,不同意!" << endl;
        }
    }
};

测试用例:

cpp 复制代码
#include <memory>

int main()
{
    std::unique_ptr<Handler> pGroupLeader = new CGroupLeader;
    std::unique_ptr<Handler> pDeptLeader = new CDeptManager;
    std::unique_ptr<Handler> pGeneralManager = new CGeneralManager;

    //设置责任链
    pGroupLeader->setNextHandler(pDeptLeader.get());
    pDeptLeader->setNextHandler(pGeneralManager.get());

    pGroupLeader->HandleRequest(1);
    pGroupLeader->HandleRequest(2);
    pGroupLeader->HandleRequest(5);
    pGroupLeader->HandleRequest(8);
    pGroupLeader->HandleRequest(12);
    return 0;
}

输出:

cpp 复制代码
我是组长,有权批准1天假,同意了!
我是组长,有权批准2天假,同意了!
我是部门经理,有权批准5天的假,同意了!
我是总经理,最多让你请10天假,同意了!
你请的假时间太长了,不同意!

4.总结

优点:

解耦: 责任链模式将请求的发送者和接收者解耦,请求的发送者不需要知道接收者是谁,也不需要创建接收者的实例。同时,接收者也不需要知道请求的具体内容,只需要按照自已的业务逻辑进行相应的处理。这种解耦方式使得系统更加灵活,降低了耦合度,方便进行模块化开发和测试。
链式处理:责任链模式可以形成一个处理链,请求在这个链中传递,每个节点都会对请求进行处理,这种方式可以实现复杂的业务逻辑,提高系统的可扩展性和可维护性。
动态添加节点:在运行时,可以通过动态添加或册除节点来改变处理链,从而实现动态地扩展或修改处理逻辑。这种动态性使得系统更加灵活,能够适应不同的需求变化。

缺点:

错误传播:在责任链模式中,如果某个节点处理请求时出现了错误,这个错误会沿看处理链向上传播,可能会导致整个链路崩溃。为了解决这个问题,需要确保每个节点都进行了错误处理,能够在出现错误时进行适当的处理或回退操作。
无法终止链路:在某些情况下,如果请求不满足某个节点的条件,该节点就不需要对请求进行处理,但责任链模式无法直接终止链路。为了解决这人问题,可以在节点中添加判断逻辑,当请求不满足条件时直接返可或者进行其他处理。
性能问题:由于请求会在多个节点间传递,因此责任链模式的性能可能会受到影响。特别是在请求量较大或处理逻辑较复杂的情况下,这种影响会更加明显。为了解决这个问题,可以对节点进行优化,提高处理效率,同时也可以考虑使用缓存等方式来降低请求的重复处理。
节点之间的依赖关系:在责任链模式中节点之间存在依赖关系,如果每个节点的处理逻辑发生了变化,可能会影响到其它节点。这种依频关系可能会导致系统复杂度增加,增加了维护的难度。为了避免这种情况,可以尽量减少节点之间的依赖关系,使每个节点都尽可能独立地处理请求。同时也可以采用模块化设计等方式来降低系统复杂度。

相关推荐
luj_176810 小时前
一线一区一变破解人盯人防守密码
开发语言·网络·c++·经验分享·算法
广州山泉婚姻10 小时前
C/C++动态内存:堆内存的申请、使用与释放
c++·人工智能
Jackson_GJH11 小时前
日志_图解spdlog
开发语言·c++
hansang_IR11 小时前
【题解】P4454 [CQOI2018] 破解D-H协议
c++·算法·密码学·数论
梓䈑11 小时前
【动态规划系列】路径问题、子数组 和 子序列问题、背包问题
c++·算法·动态规划
aqiu11111111 小时前
【数位 DP / 记忆化搜索】蓝桥云课 - 光轨区的 AI 数 题解
c++·算法·蓝桥杯·数位dp
2401_8685347811 小时前
长远目标 Long-term Goal 老题沿用
设计模式·需求分析
欧特克_Glodon12 小时前
OpenCV计算机视觉开发入门与实践<三十七>:OpenCV中的机器学习
c++·opencv·机器学习·计算机视觉
吃饱了得干活12 小时前
Java设计模式实战:一个支付模块的重构之旅,层层递进理解设计模式精髓
后端·设计模式·架构
老赵的博客13 小时前
c++ 之观察者模式
c++·qt