观察者之模式

#include<iostream>
#include<list>
#include<string>
#include<type_traits>
#include<functional>

using namespace std;
using namespace std::placeholders;
struct metadata
{
    int Temperature;
    int humidity;
    int pressure;
};

class Display {
public:
    // virtual ~Display () = 0;
    virtual void Update(const metadata& data) = 0;
    virtual std::string& GetName() { return m_name; };
    virtual void SetName(const std::string& name) { m_name = name; };
    virtual void callback(metadata& data);
private:
    std::string m_name;
};
class Temperature : public Display
{
public:
    Temperature() {
        SetName("Temperature");
    };
    ~Temperature() {};
    void Update(const metadata& data) override;
};
void Temperature::Update(const metadata& data)
{
    std::cout << " Temperature: " << data.Temperature << std::endl;
}
class Humidity : public Display
{
public:
    Humidity() {
        SetName("Humidity");
    };
    ~Humidity() {};
    void Update(const metadata& data) override;
};
void Humidity::Update(const metadata& data)
{
    std::cout << " Humidity:   " << data.humidity << std::endl;
}
using DataCB = std::function<void(metadata& data)>;//申明指针类型
//数据端
class BaseData{
    public:
        BaseData();
    void notify(metadata& data);
    void SetWeatherData(WeatherData* data){m_weatherdata = data;};
    metadata     m_data;
    WeatherData* m_weatherdata;
};
BaseData::BaseData()
{
}
void BaseData::notify(metadata& data)
{
    m_weatherdata->update(data);
}
class WeatherData
{
public:
    WeatherData();
    ~WeatherData() {};
    void Init();
    void Update();//通知每一个订阅者
    void AddSubscriber(Display* subscriber);//添加订阅者
    void RemoveSubscriber(Display* subscriber);//移除订阅者
    void ADDregistercb(DataCB cb){
        m_ldataCB.push_back(cb);    
    }
    void notify(metadata& data)
    {
        for(auto& cb : m_ldataCB)
        {
            cb(data);
        }
    }

private:
    std::list<Display*> m_observers;
    metadata            m_data;//下一步添加回调函数来通知修改数据,修改数据在通知display
    std::list<DataCB>   m_ldataCB;
};
void WeatherData::Init()
{

}
WeatherData::WeatherData()
{
    m_data.Temperature = 10;
    m_data.humidity = 20;
    m_data.pressure = 30;
}
void WeatherData::AddSubscriber(Display* subscriber)
{
    auto it = m_observers.begin();
    for (; it != m_observers.end(); it++)//防止同一类型的订阅者重复订阅
    {
        std::cout << " obsername :  " << (*it)->GetName() << "  subscriber  : " << subscriber->GetName()<<std::endl;
        if ((*it)->GetName() == subscriber->GetName())//之前订阅过
        {
            break;
        }
    }
    m_observers.push_back(subscriber);
}
void WeatherData::Update()
{
    for (auto& observer : m_observers)
    {
        observer->Update(m_data);
    }
}
void WeatherData::RemoveSubscriber(Display* subscriber)
{
    for (auto& observer : m_observers)
    {
        std::cout << observer->GetName() << std::endl;
        if ((*observer).GetName() == subscriber->GetName())
        {
           m_observers.remove(observer);
           return ;
        }
    }
}



int main(int argc, char* argv[])
{
    WeatherData *weatherData =new WeatherData();
    BaseData *adata= new BaseData();
    Display *t =new Temperature();
    Display *hum = new Humidity();
    weatherData->AddSubscriber(hum);
    weatherData->AddSubscriber(t);
    metadata    data{50,50,0};

    weatherData->ADDregistercb(std::bind(&Display::callback,t,std::placeholders::_1));
    weatherData->ADDregistercb(std::bind(&Display::callback,hum,std::placeholders::_1));
    adata->SetWeatherData(weatherData);
    adata->notify(data);




    // std::string s;   //空字符
    // while (std::getline(std::cin, s))
    // {
    //     if (!s.empty())
    //     {
    //         std::string str = s.substr(0, 2);
    //         if (str == "1w")
    //         {
    //             weatherData.AddSubscriber(t);
    //         }
    //         else if (str == "1h")
    //         {
    //             weatherData.AddSubscriber(hum);
    //         }
    //         else if (str == "0w")
    //         {
    //             weatherData.RemoveSubscriber(t);

    //         }
    //         else if (str == "0h")
    //         {
    //             weatherData.RemoveSubscriber(hum);
    //         }
    //         weatherData.Update();
    //     }
    // }
    return 0;
}
posted @ 2024-09-08 13:08  你看起来丿很好吃  阅读(18)  评论(0)    收藏  举报