Search code examples
c++design-patternssignalsobserver-patternsignals-slots

How to use signals and slots for observer pattern?


I wrote a simple observer pattern, where the observer has "void notify(std::string)" function and the observable object calls it on every registered observer and uses tokenized string to transfer the data. This is very simple, easy and works, but I need to go step forward.

I need to implement it with signal and slots (for example using boost::signals2). However I don't know how exactly slot and signals should look like and how they should be placed. I also have no idea how to allow registering whatever function I want and not only void (string).

I couldn't find any good resource which uses signals and slots for this pattern. Yet everyone says that signals and slots are amazing for observer pattern. Could you guide me how should signals and slots be used for the observer pattern?

My current implementation without signals is as follows:

class observable
{
public:
void register(observer *);
void unregister(observer *);
protected:
void notifyObservers()
   {
    for every registered observer
    observer.notify(std::string tokenized_string);
   }
}

class observer
{
public:
void notify(std::string) = 0;
}

I need to change this pattern to use signals and slots but I have no idea how it should like to be useful and well-designed and flexible.


Solution

  • How does the Observer pattern work ?

    • Observable objects are "watched" by Observer objects
    • When an Observable is modified, it notifies all of its observers a change has been made, for example by calling their "update" or "notify" function (or whatever)

    So, in terms of signals and slots. The basics are that you connect signals to slots, which will be called each time the signal they're connected to is emitted.

    You will find that it is very easy to use in the Observer pattern : just create a signal in the Observable that will be connected to the slot of each Observer used to update it.

    in case of a change in the Observable. Instead of looping through the list of all your observers, and calling their update method one after another, just emit the signal. The corresponding slots will magically be called.

    To go further, you could for example have a slot in the Observable, connected to a signal that an Observer will emit to tell the Observable it has to be noticed in case of changes...

    Can't get you a fully working example code since I never used Boost::signals2, but you should take a look at How do I use boost::signals to implement the observer pattern? and Observer design pattern in C++ to get you going :)