Click here to Skip to main content
12,510,836 members (54,300 online)
Click here to Skip to main content
Add your own
alternative version

Stats

129.6K views
878 downloads
60 bookmarked
Posted

Implementing a Subject/Observer pattern with templates

, 10 Mar 2003
Rate this:
Please Sign up or sign in to vote.
Using C++ Templates to overcome some of the original Subject/Observer design pattern problems
<!-- Download Links --> <!-- Add the rest of your HTML here -->

Introduction

The traditional Subject/Observer pattern as described in the famous Design Patterns book has one annoying disadvantage: the observer does not get a handle to the notifying subject in its update method. This means that:
  • The observer needs to store a pointer to the subject to which it is attached.
  • If the observer is attached to multiple objects, it has no way of determining which one of them is notifying him.
This article tries to solve these problems by making use of C++ templates.

The original design pattern

The original design pattern makes use of two base classes: Subject and Observer. The Subject base class contains all the logic of storing all the attached observers. The Observer class just contains a pure virtual method (update()), that needs to be filled in by the inheriting observer class. Please read the 'Design Patterns' book for all details. The update() method of the Observer class does not get any parameters, which means that a class that inherits from Observer does not know where the notification came from. It is not difficult to add a 'Subject' parameter to the update method, but since the real subject inherited from the 'Subject' base class, the observing class always needs to perform a down-cast, which could be dangerous.

The solution

Instead of defining two base classes, we will define two template clases. Both template classes will be based on the subject-class that is able to notify other classes (the observers).
template <class T>
class Observer
   {
   public:
      Observer() {}
      virtual ~Observer() {}
      virtual void update(T *subject)= 0;
   };
The first enhancement here is that our pure virtual update method gets a pointer to the subject as argument; not the base Subject class (which is shown hereafter), but the class that was given as parameter to the template definition.
template <class T>
class Subject
   {
   public:
      Subject() {}
      virtual ~Subject() {}
      void attach (Observer<T> &observer)
         {
         m_observers.push_back(&observer);
         }
      void notify ()
         {
         std::vector<Observer<T> *>::iterator it;
         for (it=m_observers.begin();it!=m_observers.end();it++) 
              (*it)->update(static_cast<T *>(this));
         }
   private:
      std::vector<Observer<T> *> m_observers;
   };
Here, we defined the basic Subject class/template. The attach method simply adds the observer (which is of the basic Observer<T> class) to a vector. The notify method simply notifies all observers. Both templates can be used in any situation where the Subject/Observer pattern can be used. The following classes describe how they are used.
class Temperature : public Subject<Temperature>
   {
   public:
      Temperature() {}
      ~Temperature() {}
      void temperatureChanged () {notify();}
      void getTemperature() {std::cout << 
         "   Getting the temperature." << std::endl;}
   };
Our Temperature class is a class that monitors the temperature, and notifies its observers when the temperature changes. As you can see all it has to do is call the notify() method. The getTemperature method simply writes something on the screen, but of course in real-life situations it should return the actual temperature. Taking a look at the implementation of the notify() method. It simply calls the update() method of all attached observers, but with itself as argument. Since 'this' (which is the Subject

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author


You may also be interested in...

Pro
Pro

Comments and Discussions

 
GeneralNotification on a Observer vector copy and other stuff Pin
MyttO22-Apr-03 5:53
memberMyttO22-Apr-03 5:53 
GeneralRe: Notification on a Observer vector copy and other stuff Pin
-Dan-13-Jul-04 14:25
suss-Dan-13-Jul-04 14:25 
GeneralRe: Notification on a Observer vector copy and other stuff Pin
Patje14-Jul-04 21:18
memberPatje14-Jul-04 21:18 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160929.1 | Last Updated 11 Mar 2003
Article Copyright 2002 by Patje
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid