• 设计模式之观察者模式(优先使用对象组合的原则)的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博客

  • 相关阅读:
    力扣代码学习日记五
    综合管廊安全监测系统,城市‘里子’的守护者
    【AGC】如何解决事件分析数据本地和AGC面板中显示不一致的问题?
    Allegro在测量时如何同时显示双单位
    【C/C++】结构体内存分配问题
    智慧风电场Web组态集控中心远程监控系统
    陕西秦创原创新驱动平台案例解读
    使用 C 语言快速排序将字符串按照 ASCII 码升序排列
    【广州华锐互动】VR可视化政务服务为公众提供更直观、形象的政策解读
    LeetCode: 4. Median of Two Sorted Arrays
  • 原文地址:https://blog.csdn.net/hanxiaoyong_/article/details/138031751