#include #include #include // ==== Classic Observer Pattern ============================================== #include #include using namespace std; namespace FIXUP { // FIXUP Needed when using BC5.02 because mem_fun is not implemented. // FIXUP Needed when using VC5.0 because mem_fun implementatiom in // function.h has problems with member functions that return void. template class mem_fun_t: public unary_function { void(T::*pmf)(); public: explicit mem_fun_t(void(T::*p)()): pmf(p) { } void operator()(T* p) const { (p->*pmf)(); } }; template mem_fun_t mem_fun(void(T::*f)()) { return mem_fun_t(f); } } // END FIXUP // == Observer == class Observer { public: virtual void update() =0; protected: virtual ~Observer() { } }; // == Subject == class Subject { public: void attach(Observer* o) { observers.push_front(o); } void detach(Observer* o) { observers.remove(o); } protected: virtual ~Subject() { } void notify() { using FIXUP::mem_fun; for_each(observers.begin(), observers.end(), mem_fun(&Observer::update)); } private: list observers; }; // ==== Application that uses the Classic Observer Pattern ==================== // == ConcreteSubjects == class Register: public Subject { public: Register(): value(0) { } Register(short init): value(init) { } void set(short v) { value=v; notify(); } short get() const { return value; } private: short value; }; class Pin: public Subject { public: Pin(): value(false) { } Pin(bool init): value(init) { } void set(bool v) { value=v; notify(); } bool get() const { return value; } private: bool value; }; // == ConcreteObservers == class DecRegisterDisplay: public Observer { public: DecRegisterDisplay(Register& r, const string& n): reg(r), name(n) { reg.attach(this); } virtual ~DecRegisterDisplay() { reg.detach(this); } virtual void update() { cout<