/* * C++ Design Patterns: Observer * Author: Jakub Vojvoda [github.com/JakubVojvoda] * 2016 * * Source code is licensed under MIT License * (for more details see LICENSE) * */ #include #include class Subject; /* * Observer * defines an updating interface for objects that should be notified * of changes in a subject */ class Observer { public: virtual int getState() = 0; virtual void update(Subject *subject) = 0; // ... }; /* * Concrete Observer * stores state of interest to ConcreteObserver objects and * sends a notification to its observers when its state changes */ class ConcreteObserver : public Observer { public: ConcreteObserver(int state) : observer_state(state) {} int getState() { return observer_state; } void update(Subject *subject); // ... private: int observer_state; // ... }; /* * Subject * knows its observers and provides an interface for attaching * and detaching observers */ class Subject { public: void attach(Observer *observer) { observers.push_back(observer); } void detach(int index) { observers.erase(observers.begin() + index); } void notify() { for (unsigned int i = 0; i < observers.size(); i++) { observers.at(i)->update(this); } } virtual int getState() = 0; virtual void setState(int s) = 0; // ... private: std::vector observers; // ... }; /* * Concrete Subject * stores state that should stay consistent with the subject's */ class ConcreteSubject : public Subject { public: int getState() { return subject_state; } void setState(int s) { subject_state = s; } // ... private: int subject_state; // ... }; void ConcreteObserver::update(Subject *subject) { observer_state = subject->getState(); std::cout << "Observer state updated." << std::endl; } int main() { ConcreteObserver observer1(1); ConcreteObserver observer2(2); std::cout << "Observer 1 state: " << observer1.getState() << std::endl; std::cout << "Observer 2 state: " << observer2.getState() << std::endl; Subject *subject = new ConcreteSubject; subject->attach(&observer1); subject->attach(&observer2); subject->setState(10); subject->notify(); std::cout << "Observer 1 state: " << observer1.getState() << std::endl; std::cout << "Observer 2 state: " << observer2.getState() << std::endl; return 0; }