Search code examples
c++observer-pattern

Observer pattern implementation


I had a hard time understand exactly what an observer pattern was, but I produced the following code for my project. It uses SDL. I am using the boost library to implement signals and therefore implementing my observer pattern. Does this look correct?

/* This is setting up our signal for sending observations */
boost::signals2::signal<void (char, int, int)> sig;

/* Subjects the Observer will connect with */
sig.connect(&setChest);
sig.connect(&setNonTraverse);
sig.connect(&setEntry);
sig.connect(&setExit);

std::cout << "Waiting for user-interaction. Press on the 'X' to quit" << std::endl;

while ( !quit ) {               
    status = SDL_WaitEvent(&event);   //wait for an event to occur
    switch (event.type) {           //check the event type
        case SDL_KEYDOWN:           //Check if a key was pressed.     
        key = SDL_GetKeyName(event.key.keysym.sym);
        break;
        case SDL_MOUSEBUTTONUP:
        sig(key[0],event.button.x/32,event.button.y/32);
        break;
        case SDL_QUIT:          // Click on the 'X' to close the window.
        exit ( 1 );
        break;
    }
  } //while
  return true;
}

Solution

  • Your posted code is that of the Observer.

    In the Observer pattern, the observer doesn't react directly to the subjects' state changes. Instead, the subject informs the observer of any changes by invoking the observer's callback. This is why the observer must register with the subject, instead of merely polling (checking the state in a while loop) the subject.

    I'm not too familiar with C++, but here is some Java-like pseudocode that outlines the basic idea:

    class Observer{
        public Observer(Subject subject){
            subject.register(this);
        }
        public void updateFromSubject(Subject subject){
            //respond to change
        }
    }
    
    class Subject{
        List<Observer> observers;
        public void register(Observer observer){
            observers.add(observer);
        }
        private void notifyObservers(){
            for(Observer obs : observers){
                obs.updateFromSubject(this);
            }
        }
        public void changeStateToNewState(Object o){
            .... //business logic
            notifyObservers();
    }
    

    Notice the lack of a while loop, which means that the observer simply doesn't do any work until an actual event occurs, instead of checking a flag a million times a second just to see if it changed.