I just carefully studied the observer pattern. And I wrote a demo snippet to better undertand it.
I am not so sure that if it's the right way to define IObservable& m_observable; in the pure abstract class.
Here is the demo code written in C++.
#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);
WindowDisplay bedroom_display(station_of_NewYork);
station_of_NewYork.add(&bedroom_display);
station_of_NewYork.set_temperature(15.6);
}