Posted by: Morten Nobel-Jørgensen | August 24, 2013

Observer pattern in C++11


Observer pattern is one of the classic GoF patterns. Its main motivation is to allow objects to communicate without a hardcoded coupling – in other words to keep the coupling of objects low. I’ll here discus an implementation in C++ using some the new features of C++11 (especially function objects).

I assume that you are already familiar with the observer pattern – otherwise I suggest you read the Wikipedia article and OODesign article the on the topic.

First some thoughts about classic observer pattern implementations.

  • Java: The most well known implementation is probably Java’s Observer / Observable classes. There is some limitations with this approach: It is not type-safe (it does not use generics) and it uses inheritance, which may be problematic if one class has multiple different things that should be observed.
  • JavaScript: In the HTML DOM there observer pattern implementation, which uses addEventListener(string, function) and removeEventListener(string, function), which is strongly related to the event system. If you want to use this on custom JavaScript objects, you need to implement the pattern yourself (such as in KickJS).

I prefer think of observable objects as event objects, which you can subscribe to for updates. An event object should have methods for adding listeners, removing listeners and notify. The event objects should also use template classes to pass objects in a type-safe way. The implementation should manage resources in an easy and safe way; I ended up using RAII, such that for every listener function there is created an Listener object, which removes the listener function, when this is destructed (Another reason for this approach is that the function object does not have the equal operator overloaded, which means that I need another way to identify a listener). Finally one very common usage of observer pattern is to keep values in sync, so I have created special type of listener, which can be used to keep a value synched.

The observer pattern that I ended up with looks like this:

observer-diagram

UML diagram of observer pattern implementation

An example usage of the implementation can be seen here:

class Foo {
  public:
  Foo(){
  }
  Event event;
  void setValue(int i){
    value = i;
    event.notifyListeners(i);
  }
  private:
  int value;
};
class Moo {
  public:
  Moo(Foo *f): syncVal(f->event.createSyncValue())
  {
    eventListener = f->event.createListener([](int v){
      cout<<"Value is "<<v<<endl;
    });
  }
  SyncValue syncVal;
  private:
  EventListener eventListener;
};

int main(int argc, const char * argv[])
{
  Foo f;
  {
    Moo m("Moo#1", &f);
    f.setValue(123);
    cout << "synched value " << m.syncVal.getValue()<<endl;;
    f.setValue(12);
    cout << "synched value " << m.syncVal.getValue()<<endl;;
  }
  f.setValue(1234);
  return 0;
}

The full source code is available as a Gist under the BSD New License:
Source code: https://gist.github.com/mortennobel/6327279

Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Categories

%d bloggers like this: