Boost logo

Boost :

From: Joseph Davis (joseph.davis_at_[hidden])
Date: 2000-04-06 07:54:43


I have been using the Qt Signal/Slot mechanism for about a year, and I find it to
be a practical idiom. I have not used the libsigc version (we use Qt), but I did
explore the links mentioned in this thread. Reading this also makes me wonder
whether or not the proposed submission would fill a roll in the boost library. If
the code is better, more portable, more "open", it certainly might.

My reason for replying is that there continues to be something about this idiom
that troubles me, although I haven't really put my finger on it. The GoF Design
Patterns book discuss at least 3 related design patterns that relate to this
topic. OBSERVER (293) is used to define a 1 to many dependency between subjects
and observers, so that when a subject changes state, all its dependents are
notified.

MEDIATOR (273) encapsulates how a set of objects interact, promoting loose
coupling. My first realization of how neat STL is came by implementing a basic
MEDIATOR between subjects and observers using a multimap. The main line of code is

  std::multimap<ISR_subject*, ISR_observer*> m_actionMap;

where ISR_subject and _observer are abstract base class for those types of
objects. The implementation of the entire mediator class is about 70 lines of
code.

Most applications would probably build their central MEDIATOR as a SINGLETON (127)
so that attaching and detaching actors would be easier. However, should the need
arise for different types of mediators specialized for various purposes, that could
be easily done as well.

In this approach, the mediator passes a pointer to the subject that changed to each
interested observer. The observer can then query the subject for data as
appropriate. Obviously, any changes in the data interface functions to concrete
subjects, will force rework on all concrete observers. Such is life.

It seems to me that signal/slot addresses these same issues and probably uses much
the same design architecture. However, client code tends to be vectored away from
the MEDIATOR implementation. It seems to work well if the relationship between
the object that emits the signal and the object that hold the slot can be neatly
handled by relatively simple data like that between GUI primitives like buttons and
edit boxes.

In other words, signal/slot may not really be appropriate if the object with the
slot really does need to observe changes in state of a complex object. I suspect
that if lots of signals need to be coupled to lots of slots, then the design of the
MEDIATOR in the middle will become the focus of much optimization worries in
complex apps.

I also worry about complex interdependencies causing cascades of unnecessary
updates. The solution if you write your own MEDIATOR is to write a better
MEDIATOR.

Sorry for the long winded reply. I suppose my main worry is that overuse of
signal/slot could lead to big troubles with medium to large designs. It seems fine
for certain rolls, like wiring GUI elements into your app.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk