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

发布于:2024-04-25 ⋅ 阅读:(19) ⋅ 点赞:(0)

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

代码实现如下:

#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博客