#include <iostream>
#include <list>
template<typename T>
class Observer {
public:
//private:
virtual void notify(const T& data) = 0;
public:
virtual ~Observer() = default;
};
template<typename T>
class Subject {
public:
void subscribe(Observer<T> *observer);
void unsubscribe(Observer<T> *observer);
virtual ~Subject() = default;
protected:
void notify(const T& data);
private:
std::list<Observer<T>*> observers;
};
template<typename T>
void Subject<T>::subscribe(Observer<T> *observer) {
this->observers.push_back(observer);
}
template<typename T>
void Subject<T>::unsubscribe(Observer<T> *observer) {
this->observers.remove(observer);
}
template<typename T>
void Subject<T>::notify(const T& data) {
for (const auto &observer: this->observers) {
observer->notify(data);
}
}
struct MoveData{};
struct SteerData{};
class Car : public Subject<MoveData>, public Subject<SteerData> {
public:
void move() {
const MoveData moveData{};
this->Subject<MoveData>::notify(moveData);
}
void steer() {
const SteerData steerData{};
this->Subject<SteerData>::notify(steerData);
}
};
struct MoveDataObserver : Observer<MoveData>
{
void notify(const MoveData&) override { std::cout << "MoveDataObserver\n"; }
};
struct SteerDataObserver : Observer<SteerData>
{
void notify(const SteerData&) override { std::cout << "SteerDataObserver\n"; }
};
int main()
{
Car car;
MoveDataObserver obs1;
SteerDataObserver obs2;
car.Subject<MoveData>::subscribe(&obs1);
car.Subject<SteerData>::subscribe(&obs2);
car.move();
car.steer();
}