/* * observer.cpp * * Example of Observer Pattern. * * Define relationship between a group of objects such that * whenever one object is updated all others are notified * automatically. */ #include #include #include class Observer; class Subject { public: // add an observer void attach(Observer* observer) { observers.insert(observer); } // remove an observer void detach(Observer* observer) { observers.erase(observer); } // notify all observers virtual void notify(); private: std::set observers; }; class Observer { public: virtual void update() = 0; }; class ConcreteSubject : public Subject { public: virtual int getState() const { return _state; } virtual void setState(int new_state) { std::cout << "Setting new state " << new_state << std::endl; _state = new_state; notify(); } private: int _state; }; class ConcreteObserver : public Observer { public: ConcreteObserver(int id, ConcreteSubject& subject): _id(id), _subject(subject) { _subject.attach(this); } ~ConcreteObserver() { _subject.detach(this); } virtual void update() { _observer_state = _subject.getState(); std::cout << _id << " updated to new state " << _observer_state << std::endl; } private: ConcreteSubject& _subject; int _id; int _observer_state; }; void Subject::notify() { for (std::set::iterator it = observers.begin(); it != observers.end(); ++it) (*it)->update(); } int main() { // create the subject server ConcreteSubject subject; // create an observers and attach it to the server ConcreteObserver observer1(1, subject); // change the state subject.setState(123); { // create another observers and attach it to the server ConcreteObserver* pobserver2 = new ConcreteObserver(2, subject); // change the state subject.setState(456); delete pobserver2; } // remove the first observer subject.detach(&observer1); // change the state subject.setState(789); }