Main Page Namespace List Class Hierarchy Compound List Compound Members

# ZThread::Observable Class Template Reference

`#include <Observable.h>`

Inheritance diagram for ZThread::Observable::

List of all members.

## Public Methods
| Observable ()
| Observable (LOCK *)
virtual | ~Observable () throw ()
virtual void | subscribe (T *)
virtual void | unsubscribe (T *)
void | notify () const
template<class U> void | notify (const U &u) const
template<class U, class V> void | notify (const U *u, const V &v) const

## Detailed Description

### template<class T, class LOCK = Mutex> class ZThread::Observable

Author:
  Eric Crahen

Version:
  1.4.1

Date:
  04-28-2001

This is a very useful template for creating objects that work using the Observer pattern. You can use this template for both weakly typed listeners and strongly typed listeners. By weakly or strongly typed listeners, I mean listener objects that just implicitly define the needed notify methods (weak) to a listener derived from a virtual base that defines the needed notify methods (strong). Better explanation is given with the examples below.

The template creates the subject of the observer pattern to which listener objects of type 'T' can subscribe to. The listener objects are notified of each event as the notify() methods of the Observable object are invoked

The only requirement is that the listener object must implement the correct notify methods. So if you are using a parameterless notify() method on the Observer - the you need only implement notify() on the listener class. If you use a parameterized notify method, then you need implement the correct type method.

This means if you are calling notify(int) on the observer, then the listener class needs to implement the notify(int) method. These listener notify methods should be public

You need only to implement the notify function you use. This template includes three types of notify() methods, but if you don't use them all the compiler will ignore the unused portions of the template quietly.

The nice thing about this template is that is very flexible.

Consider a case where you have several type of log events, and you have an object that is interested in all of these event types - but will not necessarily take the take action for each. It might just be easier in general to implement a class with the different notify functions on them directly rather than creating several virtual base classes for each type and inheriting from them all. Of you may want to define a single virtual base class that implements all three of the needed notify() functions and maintain a strongly type system. Its up to the programmer how to define his listener classes no inheritance is forced here unless the programmer wishes to impose it, and no one is forced to use implicitly defined notify() methods either.

       Observer<ListenerType> O;
       ListenerType L;

       O.subscribe(&L);

       O.notify( int(9) ); // Basic example
       O.notify( "Hello" );

       // Or

       O.notify( LogMessage("Its OK") ); // More useful example
       O.notify( LogCritical("Error!") );

     }

The ListenerType can be implemented as (Assuming LogMessage & LogCritical are valid classes)

     // Weakly typed listener
     // just implements the notify methods that are implicitly defined
     // in the template
     class ListenerType {
     public:

       void notify(LogMessage);  // These are function signatures for
       void notify(LogCritical); // simplicity sake

     };

     // Strongly typed listener

     // The base just implements the notify methods that are implicitly defined
     // in the template, but forced some class to derive from this. The programmer
     // will need to realize what functions the observer will need to call to
     // define the abstract base correctly.
     class ListenerBaseType {
     public:

       virtual ~ListenerBaseType() {}

       virtual void notify(LogMessage) = 0;
       virtual void notify(LogCritical) = 0;

     };

     class ListenerImpl : public ListenerBaseType {
     public:

       virtual void notify(LogMessage);
       virtual void notify(LogCritical);

     };

## Constructor & Destructor Documentation

Observable ( | )

| Create a new Observable object that owns its own Lockable object (which is used to manipulate its data)

Observable ( | LOCK * lock )

  | Create a new Observable object that shares it Lockable object (which is used to manipulate its data) Parameters:
  LOCK | * - lock owned by some other object
  Parameters:
  lock |

~Observable ( | ) throw ()`[virtual]`

| Destroy this Observable

## Member Function Documentation

void notify ( | const U * u,
| const V & v ) const`[inline]`

  | Distribute an event of type U to all subscribed objects, via their double parameter notify function Parameters:
  u |
  v |

void notify ( | const U & u ) const`[inline]`

  | Distribute an event of type U to all subscribed objects, via their single parameter notify function Parameters:
  u |

void notify ( | ) const`[inline]`

| Distribute an event of type U to all subscribed objects, via their no-parameter notify function

void subscribe ( | T * l )`[virtual]`

  | Subscribe to an observer Parameters:
  l |

void unsubscribe ( | T * l )`[virtual]`

  | Unsubscribe from an observer Parameters:
  l |

The documentation for this class was generated from the following file:

- Observable.h