Re: Observer Design Pattern
 
Krivenok Dmitry wrote:
Hello All!
I am trying to implement my own Design Patterns Library.
You can't do that in general. Design Patterns are at a level higher
than simple code reuse. That said...
The classic "pull model" can be implemented like this:
class Observer
{
public:
    virtual ~Observer() { }
    virtual void update() = 0;
};
class Subject
{
    std::set< Observer* > observers;
public:
    void attach( Observer* o ) {
        observers.insert( o );
    }
    void detach( Observer* o ) {
        observers.erase( o );
    }
    void notify() {
        for_each( observers.begin(), observers.end(),
                                    mem_fun( &Observer::update ) );
    }
};
class MySubject : public Subject
{
    int state;
public:
    int getState() const { return state; }
    void setState( int value ) { state = value; notify(); }
};
class MyObserver : public Observer
{
    MyObserver( const MyObserver& );
    MyObserver& operator=( const MyObserver& );
    MySubject* subject;
public:
    MyObserver( MySubject* subject_ ): subject( subject_ ) {
        subject->attach( this );
    }
    ~MyObserver() {
        subject->detach( this );
    }
    void update() {
        // do something with subject->getState();
    }
};
However, I have found the "push model" to be much more useful:
    template < typename Observer >
class Subject {
    std::set< Observer* > observers;
public:
    void attach( Observer* o ) {
        observers.insert( o );
    }
    void detach( Observer* o ) {
        observers.erase( o );
    }
        template < typename ConcreteSubject >
    void notify( const ConcreteSubject* cs, void (Observer::*fn)( const
ConcreteSubject* ) ) {
        std::set< Observer* >::iterator it = observers.begin();
        while ( it != observers.end() ) {
            Observer* ob( *it++ );
            (ob->*fn)( cs );
        }
    }
};
I don't understand why GoF includes GetState method in Subject's
interface.
They did that because they were looking at SmallTalk examples which
didn't translate well to C++
Main question:
How to avoid type switching in ConcreteObserver::Update(Subject* s)?
As I showed above.