Question about observer pattern. How about there is an observer need information from two or more sources

  Kiến thức lập trình

I just carefully studied the observer pattern. And I wrote a demo snippet to better undertand it.
But after I just finished the demo, a question arose, the observer pattern is between one obserable objects and many observers. How about there is an observer need information from two or more sources?

Here is the demo code written in C++ to make you understand my quesiton better(Please pay attention to my comment in the code snippet below):

#include<list>
#include<algorithm>
#include<iostream>
#include<string>

class IObserver;

class IObservable
{
public:
    virtual void add(IObserver*) = 0;
    virtual void remove(IObserver*) = 0;
    virtual void trigger() = 0;
    virtual double get_temperature() = 0;
    virtual ~IObservable() = default;
};

class IObserver
{
public:
    IObserver(IObservable& observable):m_observable(observable){}
    virtual void update() = 0;
    virtual ~IObserver() = default;
protected:
    IObservable& m_observable;
};

class IDisplay
{
public:
    virtual void display() = 0;
    virtual ~IDisplay() = default;
};

class WeatherStation : public IObservable
{
public:
    void add(IObserver* observer_ptr) override
    {
        if(std::find(m_observer_list.begin(), m_observer_list.end(), observer_ptr) == m_observer_list.end())
        {
            m_observer_list.push_back(observer_ptr);
        }
    }

    void remove(IObserver* observer_ptr) override
    {
        m_observer_list.erase(std::remove(m_observer_list.begin(), m_observer_list.end(), observer_ptr), m_observer_list.end());
    }
    
    void trigger()
    {
        for(const auto& observer:m_observer_list)
        {
            observer->update();
        }
    }

    double get_temperature()
    {
        return m_temperature;
    }

    void set_temperature(double temperature)
    {
        m_temperature = temperature;
        trigger();
    }

    virtual ~WeatherStation() = default;
private:
    std::list<IObserver*> m_observer_list;
    double m_temperature;
};

class CommonDisplay:public IObserver, public IDisplay
{
public:
    CommonDisplay(IObservable& observable):IObserver(observable){}

    virtual ~CommonDisplay() = default;

    void update() override
    {
        display();
    }

};

class PhoneDisplay:public CommonDisplay
{
public:
    PhoneDisplay(IObservable& observable, const std::string& name): m_name(name),CommonDisplay(observable){}

    void display() override
    {
        std::cout << m_name << "'s phone displayed, temperature: " << m_observable.get_temperature() << std::endl;
    }
private:
    std::string m_name = "unknown";
};


class WindowDisplay:public CommonDisplay
{
public:
    WindowDisplay(IObservable& observable):CommonDisplay(observable){}

    void display() override
    {
        std::cout << "WindowDisplay displayed, temperature: " << m_observable.get_temperature() << std::endl;
    }
};



int main()
{
    WeatherStation station_of_NewYork;
    WeatherStation station_of_Seattle;

    PhoneDisplay jone_phone(station_of_NewYork, "Jhone");
    PhoneDisplay lucy_phone(station_of_NewYork, "Lucy");
    station_of_NewYork.add(&jone_phone);
    station_of_NewYork.add(&lucy_phone);

    //If Lucy also what's to know the temperature of Seattle, how to achieve that goal?

    WindowDisplay bedroom_display(station_of_NewYork);
    station_of_NewYork.add(&bedroom_display);

    station_of_NewYork.set_temperature(15.6);
}

LEAVE A COMMENT