• 责任链模式(Chain Of Responsibility)


    参考:

    设计模式-责任链模式

    design-patterns-cpp/Proxy.cpp at master · JakubVojvoda/design-patterns-cpp · GitHub

    一、什么是责任链模式?

    定义:将用户的请求,通过拆解,传递给多处理者按顺序处理。它们有相同的输入,且每个处理者中都包含下一个处理者对象(最后一个处理者可以没有后继),像链表一样有者先后顺序。这样,可以通过调整链表的结构来改变请求的处理流程。

    比如,员工报销需要找组长、经理、部长、账务行签字,特殊时期想简化报销流程,可以去除组长、经理等审批环节;或者审批到经理就没有通过,也就不需要走后续流程。甚至还可以添加其它审批环节,但要求所有的审批者都有相同的输入,就是审批单。

    在这里插入图片描述

    二、实现

    责任链(Chain Of Responsibility)模式包含以下主要角色:

    1. 处理者 (Handler):声明了所有具体处理者的通用接口。 该接口通常仅包含单个方法用于请求处理, 但有时其还会包含一个设置链上下个处理者的方法。
    2. 基础处理者 (Base Handler):是一个可选的类, 你可以将所有处理者共用的样本代码放置在其中。
      通常情况下, 该类中定义了一个保存对于下个处理者引用的成员变量。 客户端可通过将处理者传递给上个处理者的构造函数或设定方法来创建链。 该类还可以实现默认的处理行为: 确定下个处理者存在后再将请求传递给它。
    3. 具体处理者 (Concrete Handlers):包含处理请求的实际代码。 每个处理者接收到请求后, 都必须决定是否进行处理, 以及是否沿着链传递请求。
      处理者通常是独立且不可变的, 需要通过构造函数一次性地获得所有必要地数据。
    /*
     * C++ Design Patterns: Chain of Responsibility
     * Author: Jakub Vojvoda [github.com/JakubVojvoda]
     * 2016
     *
     * Source code is licensed under MIT License
     * (for more details see LICENSE)
     *
     */
    #include 
    
    /*
     * 处理者 (Handler):声明了所有具体处理者的通用接口。 
     * 该接口通常仅包含单个方法用于请求处理, 但有时其还会包含一个设置链上下个处理者的方法
     */
    class Handler
    {
    public:
      virtual ~Handler() {}
      
      virtual void setHandler( Handler *s )
      {
        successor = s;
      }
      
      virtual void handleRequest()
      {
        if (successor != 0)
        {
          successor->handleRequest();
        }
      }
      // ...
    
    private:
      Handler *successor;
    };
    
    /*
     * 具体处理者 (Concrete Handlers):包含处理请求的实际代码。 
     * 每个处理者接收到请求后, 都必须决定是否进行处理, 以及是否沿着链传递请求。
     */
    class ConcreteHandler1 : public Handler
    {
    public:
      ~ConcreteHandler1() {}
      
      bool canHandle()
      {
        // ...
        return false;
      }
      
      virtual void handleRequest()
      {
        if ( canHandle() )
        {
          std::cout << "Handled by Concrete Handler 1" << std::endl;
        }
        else
        {
          std::cout << "Cannot be handled by Handler 1" << std::endl;
          Handler::handleRequest();
        }
        // ...
      }
      // ...
    };
    
    class ConcreteHandler2 : public Handler
    {
    public:
      ~ConcreteHandler2() {}
      
      bool canHandle()
      {
        // ...
        return true;
      }
      
      virtual void handleRequest()
      {
        if ( canHandle() )
        {
          std::cout << "Handled by Handler 2" << std::endl;
        }
        else
        {
          std::cout << "Cannot be handled by Handler 2" << std::endl;
          Handler::handleRequest();
        }
        // ...
      }
      
      // ...
    };
    
    
    int main()
    {
      ConcreteHandler1 handler1;
      ConcreteHandler2 handler2;
      
      handler1.setHandler( &handler2 );
      handler1.handleRequest();
      
      return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108

    三、优缺点

    优点

    • 与链表一样,方便添加、删除、调整处理顺序。
    • 每个处理者可以选择,是否将请求继续传递下去。

    缺点

    • 所有的处理者都需要实现统一的处理接口,也就意味着,处理着相同的输入。
  • 相关阅读:
    【Computer Vision】基于ResNet-50实现CIFAR10数据集分类
    axios 实现请求 loading 效果
    LN论文、五种归一化原理和实现
    安卓手机APP开发__媒体开发部分__网络栈
    一起Talk Android吧(第四百二十三回:给图片添加阴影)
    服务端渲染学习笔记
    你了解计算机视觉目标分类、识别、检测、分割任务吗,一文读懂这些CV问题
    大数据-之LibrA数据库系统告警处理(ALM-12039 GaussDB主备数据不同步)
    新旧电脑间文件互传(通过网络)
    开学季征文|卷生卷死之新学期大学生自救指南!!!
  • 原文地址:https://blog.csdn.net/I_just_smile/article/details/126087050