• 设计模式之观察者模式(优先使用对象组合的原则)的C++实现


    观察者模式又称订阅者发布者模式,本篇介绍主要是利用对象组合大于类继承的设计模式原则实现订阅发布模式,这种设计的优点是想订阅数据的类不需要继承订阅者类的抽象类,减少了一层类的继承;当然,具体情况需要可根据需求进行订阅者发布者模式的代码设计。

    代码实现如下:

    1. #include
    2. #include
    3. #include
    4. #include
    5. using Callback = std::function<void(int)>;
    6. class Subcribe{
    7. public:
    8. Subcribe(Callback func):m_callback(std::move(func)){
    9. };
    10. void RecievData(int val)
    11. {
    12. printf("Recive data val = %d \n",val);
    13. m_callback(val);
    14. }
    15. private:
    16. Callback m_callback;
    17. };
    18. //单例基类
    19. template<class T>
    20. class SingleIns{
    21. public:
    22. static T& GetInstance()
    23. {
    24. static T a;
    25. return a;
    26. }
    27. protected:
    28. SingleIns()=default;
    29. };
    30. class Publisher:public SingleIns{
    31. public:
    32. void Attach(Subcribe* obj)
    33. {
    34. if(std::count(m_vecSubscribers.begin(),m_vecSubscribers.end(),obj) > 0)
    35. {
    36. printf("Attach the subscriber already exist\n");
    37. return;
    38. }
    39. m_vecSubscribers.push_back(obj);
    40. };
    41. void Detach(Subcribe* obj){
    42. auto it = std::find(m_vecSubscribers.begin(),m_vecSubscribers.end(),obj);
    43. if(it != m_vecSubscribers.end())
    44. {
    45. m_vecSubscribers.erase(it);
    46. }
    47. }
    48. void UpdateVal(int val)
    49. {
    50. if(m_vecSubscribers.size() == 0)
    51. {
    52. printf("The m_vecSubscribers is empty\n");
    53. return;
    54. }
    55. if(m_val != val)
    56. {
    57. m_val = val;
    58. Notify();
    59. }else{
    60. printf("The updated data is equal\n");
    61. }
    62. }
    63. private:
    64. void Notify()
    65. {
    66. for(auto it = m_vecSubscribers.begin();it !=m_vecSubscribers.end();it++)
    67. {
    68. (*it)->RecievData(m_val);
    69. }
    70. };
    71. std::vectorm_vecSubscribers;
    72. int m_val;
    73. };
    74. class User1{
    75. public:
    76. void GetData(int val)
    77. {
    78. printf("User1 Get data = %d\n",val);
    79. };
    80. void Init()
    81. {
    82. Publisher::GetInstance().Attach(&m_subscirbe);
    83. }
    84. Subcribe& GetSubObj(){return m_subscirbe;}; //对象组合
    85. private:
    86. Subcribe m_subscirbe{std::bind(&User1::GetData,this,std::placeholders::_1)};
    87. };
    88. class User2{
    89. public:
    90. void GetData(int val)
    91. {
    92. printf("User1 Get data *2 = %d\n",val*2);
    93. };
    94. void Init()
    95. {
    96. Publisher::GetInstance().Attach(&m_subscirbe);
    97. }
    98. Subcribe& GetSubObj(){return m_subscirbe;}; //对象组合
    99. private:
    100. Subcribe m_subscirbe{std::bind(&User2::GetData,this,std::placeholders::_1)};
    101. };
    102. int main()
    103. {
    104. User1 obj;
    105. obj.Init();
    106. Publisher::GetInstance().UpdateVal(1);
    107. Publisher::GetInstance().UpdateVal(2);
    108. Publisher::GetInstance().UpdateVal(3);
    109. Publisher::GetInstance().UpdateVal(3);
    110. Publisher::GetInstance().Detach(&obj.GetSubObj());
    111. Publisher::GetInstance().UpdateVal(6);
    112. printf("\n**************************\n\n");
    113. User2 obj2;
    114. obj2.Init();
    115. Publisher::GetInstance().UpdateVal(5);
    116. Publisher::GetInstance().UpdateVal(6);
    117. Publisher::GetInstance().Detach(&obj2.GetSubObj());
    118. Publisher::GetInstance().UpdateVal(7);
    119. return 0;
    120. }

    程序运行结果如下:

    7377db541f0d401594075079cd515498.png

    附加知识:单例模式C++实现和观察者模式C++实现_实现观察者模式,并画出其类图 c++-CSDN博客

  • 相关阅读:
    微软广告和网络服务CEO承认OpenAI的Sora将加入Copilot,但需要一些时间
    Springboot - 3.BeanFactory
    中国机器人发展的机遇(赵杰)
    Docker 网络与数据管理
    数字孪生场景、代码即开即用 | 图观™引擎 超详细功能范例演示
    工具分享:清理 Markdown 中没有引用的图片
    javaScript中循环遍历的方式有哪些
    2023年中国乘用车金属冲压件产量、需求量及行业市场规模分析[图]
    【华为机试真题 JAVA】水仙花数 Ⅰ-100
    这些嵌入式知识助你秋招,也助你进阶
  • 原文地址:https://blog.csdn.net/hanxiaoyong_/article/details/138031751