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

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

代码实现如下:

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>

using Callback = std::function<void(int)>;
class Subcribe{
public:
    Subcribe(Callback func):m_callback(std::move(func)){
    };
    void RecievData(int val)
    {
        printf("Recive data val = %d \n",val);
        m_callback(val);
    }

private:
    Callback m_callback;
};


//单例基类
template<class T>
class SingleIns{
public:
    static T& GetInstance()
    {
        static T a;
        return a;
    }
protected:
    SingleIns()=default;
};

class Publisher:public SingleIns<Publisher>{
public:
    void Attach(Subcribe* obj)
    {
        if(std::count(m_vecSubscribers.begin(),m_vecSubscribers.end(),obj) > 0)
        {
            printf("Attach the subscriber already exist\n");
            return;
        }
        m_vecSubscribers.push_back(obj);
    };
    void Detach(Subcribe* obj){
        auto it = std::find(m_vecSubscribers.begin(),m_vecSubscribers.end(),obj);
        if(it != m_vecSubscribers.end())
        {
            m_vecSubscribers.erase(it);
        }
    }

    void UpdateVal(int val)
    {
        if(m_vecSubscribers.size() == 0)
        {
            printf("The m_vecSubscribers is empty\n");
            return;
        }
        if(m_val != val)
        {
            m_val = val;
            Notify();
        }else{
            printf("The updated data is equal\n");
        }
    }

private:
    void Notify()
    {
        for(auto it = m_vecSubscribers.begin();it !=m_vecSubscribers.end();it++)
        {
            (*it)->RecievData(m_val);
        }
    };
    std::vector<Subcribe*>m_vecSubscribers;
    int m_val;

};

class User1{
public:
    void GetData(int val)
    {
        printf("User1 Get data = %d\n",val);
    };
    void Init()
    {
        Publisher::GetInstance().Attach(&m_subscirbe);
    }
    Subcribe& GetSubObj(){return m_subscirbe;};  //对象组合
private:
    Subcribe m_subscirbe{std::bind(&User1::GetData,this,std::placeholders::_1)};
};

class User2{
public:
    void GetData(int val)
    {
        printf("User1 Get data *2 = %d\n",val*2);
    };
    void Init()
    {
        Publisher::GetInstance().Attach(&m_subscirbe);
    }
    Subcribe& GetSubObj(){return m_subscirbe;}; //对象组合
private:
    Subcribe m_subscirbe{std::bind(&User2::GetData,this,std::placeholders::_1)};
};

int main()
{
    User1 obj;
    obj.Init();

    Publisher::GetInstance().UpdateVal(1);
    Publisher::GetInstance().UpdateVal(2);
    Publisher::GetInstance().UpdateVal(3);
    Publisher::GetInstance().UpdateVal(3);
    Publisher::GetInstance().Detach(&obj.GetSubObj());
    Publisher::GetInstance().UpdateVal(6);
    printf("\n**************************\n\n");
    User2 obj2;
    obj2.Init();
    Publisher::GetInstance().UpdateVal(5);
    Publisher::GetInstance().UpdateVal(6);
    Publisher::GetInstance().Detach(&obj2.GetSubObj());
    Publisher::GetInstance().UpdateVal(7);

    return 0;
}

程序运行结果如下:

7377db541f0d401594075079cd515498.png

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

相关推荐

  1. C++ 设计模式观察模式

    2024-04-22 07:34:04       28 阅读
  2. 观察模式实现对象松耦合

    2024-04-22 07:34:04       13 阅读
  3. c++设计模式观察模式(消息订阅模式

    2024-04-22 07:34:04       11 阅读
  4. c#观察设计模式

    2024-04-22 07:34:04       34 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-22 07:34:04       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-22 07:34:04       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-22 07:34:04       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-22 07:34:04       18 阅读

热门阅读

  1. Spark在大数据集群下的部署

    2024-04-22 07:34:04       15 阅读
  2. Golang函数重试机制实现

    2024-04-22 07:34:04       14 阅读
  3. Deepin中安装Golang1.22

    2024-04-22 07:34:04       11 阅读
  4. 使用idea如何打开python项目

    2024-04-22 07:34:04       14 阅读
  5. 【LeetCode热题100】【子串】最小覆盖子串

    2024-04-22 07:34:04       11 阅读
  6. FFMPEG C++封装(三)

    2024-04-22 07:34:04       13 阅读
  7. Delete the specified node in the linked list with dummy header

    2024-04-22 07:34:04       11 阅读
  8. mac tcp实现客户端与服务端进行图像传输及处理

    2024-04-22 07:34:04       12 阅读
  9. 【Linux】学习记录_15_POSIX信号量

    2024-04-22 07:34:04       12 阅读
  10. 如何在 Apache 和 Nginx 上配置 OCSP Stapling

    2024-04-22 07:34:04       13 阅读
  11. 【Qt】Qt中多线程的使用

    2024-04-22 07:34:04       12 阅读