• C++行为型模式-职责链模式


    1.1 基本概念

    职责链模式(Chain of Responsibility Pattern):避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这类对象链接成一条链,并沿着这条链传递请求,直到有对象处理它为止。

    1.2 模式结构

     (1)Hander(抽象处理者)

    定义了一个处理请求的接口;

    (2)ConcreteHander(具体处理者)

    处理它所负责的请求,如果可处理该请求,就处理掉这个请求;否则将该请求转发给它的下一个可以处理该请求的对象,所以它必须能访问它的下一个可以处理同样请求的对象;

    (3)Client(客户类):

    向处理对象提出具体的请求。

    1.3 优缺点

    优点:

    • 处理者对于请求者完全透明,请求者无需事先知道谁来处理;
    • 它允许多与一个的处理者对象根据自己的逻辑来决定哪一个处理者最终处理这个命令,提高系统的扩展性;
    • 扩展灵活,新增具体请求者时无需修改原有系统的代码;
    • 责任链模式减低了发出命令的对象和处理命令的对象之间的耦合;

    缺点:

    • 产生许多细颗粒对象;
    • 不一定能被处理,可能到末端也没被处理或者中间写错;
    • 比较长的责任链,可能涉及多个处理对象,性能问题,还有调试不方便;
    • 建链不当,可能造成循环调用,导致系统进入死循环;

    1.4 应用场景

    1. 多个对象可以处理同一请求,但具体由哪个对象处理,则需要动态决定时。
    2. 在请求者不明确的情况下需要向多个对象中的一个提交请求时。
    3. 需要动态的指定一组对象处理请求时。
    4. 系统已经有一个由处理者对象组成的链。这个链可能由复合模式给出,
    5. 当系统想发出一个请求给多个处理者对象中的某一个,但是不明显指定是哪一个处理者对象会处理此请求。
    6. 当处理一个请求的处理者对象集合需要动态地指定时

    1.5 举例

    请假审批系统实现。

    1. #include
    2. using namespace std;
    3. #define SAFE_DELETE(p) if (p) { delete p; p = NULL; }
    4. //请求类 封装请求相关的信息
    5. class HolidayRequest
    6. {
    7. public:
    8. HolidayRequest(string leaveName, int leaveDays):m_leaveName(leaveName), m_leaveDays(leaveDays){};
    9. void setLeaveName(string leaveName) {
    10. m_leaveName = leaveName;
    11. }
    12. string getLeaveName(){
    13. return m_leaveName;
    14. }
    15. void setLeaveDays(int leaveDays){
    16. m_leaveDays = leaveDays;
    17. }
    18. int getLeaveDays(){
    19. return m_leaveDays;
    20. }
    21. private:
    22. string m_leaveName;
    23. int m_leaveDays;
    24. };
    25. //抽象处理者类 The holiday request handler interface
    26. class Manager
    27. {
    28. public:
    29. //抽象请求处理方法
    30. virtual bool HandleRequest(HolidayRequest *pRequest) = 0;
    31. };
    32. // 具体处理者 Project manager
    33. class PM : public Manager
    34. {
    35. public:
    36. PM(Manager *handler):m_pHandler(handler){};
    37. bool HandleRequest(HolidayRequest *pRequest)
    38. {
    39. if (pRequest->getLeaveDays() <= 3)
    40. {
    41. cout<<"PM said:OK."<
    42. cout << "leave name is " << pRequest->getLeaveName() << " and leave days is " << pRequest->getLeaveDays();
    43. return true;
    44. }
    45. else{
    46. if(m_pHandler != NULL){
    47. return m_pHandler->HandleRequest(pRequest);
    48. }
    49. }
    50. return false;
    51. }
    52. private:
    53. Manager *m_pHandler;
    54. };
    55. // 具体处理者 Department manager
    56. class DM : public Manager
    57. {
    58. public:
    59. DM(Manager *handler) : m_pHandler(handler){}
    60. bool HandleRequest(HolidayRequest *pRequest)
    61. {
    62. if (pRequest->getLeaveDays() <= 10){
    63. cout<<"DM said:OK."<
    64. cout << "leave name is " << pRequest->getLeaveName() << " and leave days is " << pRequest->getLeaveDays();
    65. return true;
    66. }
    67. else{
    68. if(m_pHandler != NULL){
    69. return m_pHandler->HandleRequest(pRequest);
    70. }
    71. }
    72. return false;
    73. }
    74. }
    75. private:
    76. Manager *m_pHandler;
    77. };
    78. //具体处理者 Project supervisor
    79. class PS : public Manager
    80. {
    81. public:
    82. PS(Manager *handler) : m_pHandler(handler){}
    83. bool HandleRequest(HolidayRequest *pRequest)
    84. {
    85. if (pRequest->getLeaveDays() <= 30){
    86. cout<<"DM said:OK."<
    87. cout << "leave name is " << pRequest->getLeaveName() << " and leave days is " << pRequest->getLeaveDays()<
    88. return true;
    89. }
    90. else{
    91. cout << "Exceed the maximum number of days off" ;
    92. return false;
    93. }
    94. return false;
    95. }
    96. private:
    97. Manager *m_pHandler;
    98. };
    99. int main()
    100. {
    101. //职责链创建
    102. DM *pDM = new DM(NULL);
    103. PS *pPS = new PS(pDM);
    104. PM *pPM = new PM(pPS);
    105. HolidayRequest *pHolidayRequest = new HolidayRequest("xiaoming",1);
    106. pPM->HandleRequest(pHolidayRequest);
    107. SAFE_DELETE(pHolidayRequest);
    108. pHolidayRequest = new HolidayRequest("xiaogang",5);
    109. pPM->HandleRequest(pHolidayRequest);
    110. SAFE_DELETE(pDM);
    111. SAFE_DELETE(pPS);
    112. SAFE_DELETE(pPM);
    113. SAFE_DELETE(pHolidayRequest);
    114. }

    PM said:OK.
    leave name is xiaoming and leave days is 1DM said:OK.
    leave name is xiaogang and leave days is 5
     

    参考文献:

    【1】C++设计模式之职责链模式(Chain of Responsibility)(行为型) | 码农家园

  • 相关阅读:
    PHY6230低成本遥控灯控芯片国产蓝牙BLE5.2 2.4G SoC
    后端各种格式传参混合vue前端传参
    深入理解右值引用与移动语义
    电脑系统重装下载的系统在哪找到
    C++的string你可能会用,但是你模拟实现过了吗?带你实现以下string的重要接口!
    从零开始学数据结构系列之第三章《二叉排序树基础了解》
    xss.pwnfunction.com靶机 Warmups
    UE AI里的感知实现流程解析
    二叉树的经典OJ题
    Linux网络技术学习(四)—— 用户空间与内核的接口
  • 原文地址:https://blog.csdn.net/kenjianqi1647/article/details/127870557