Router
Intent
Allow object to subscribe and unsubscribe from messages in an event based system.
Motivation
Windows in a GUI (graphical user interface) client program are opened and closed throughout the lifetime of the program. The server should not be aware of which windows are open, or which are interested in specific data changes.
A solution is to provide a single bridge that routes events to clients/windows at their request.
Applicability
Use the router pattern when:
- You have a changing number of event producers and consumers
- Event consumers are likely to be interested in different events over their lifetime
- The complete set of events is unknown or likely to change
- More than one consumer is likely to be interested a single event
- Performance (or similar) considerations mean that use of multiple inheritance is impractical
Structure

Participants
Producer
- Introduces events into the system in the form of Message objects
- Maintains a reference to a Queue object
Queue
- Stores a queue of pending events
Message
- Abstract base class for all types of messages in the system
- Provides a unique identifier for each derived class
Router
- Forms the main message loop by extracting events from the queue and passing them to Route objects
- Contains an object of type queue
- Contains a map from message identifiers to Route objects
Route
- Encapsulates a set of Consumer's interests for a single message type
Consumer
- Abstract base class for message consumers
- Contains a pure virtual function to handle events
Collaborations

A producer places a message on the queue.
An arbitrary time later, the router gets the message from the queue and checks its map to find if a Route exists the for message. If a Route object is found, the Message object is passed to it for processing.
The Route object loops through all its Consumer objects passing the message to each in turn.
After the message has been processed, the Router object discards it
Consequences
The router pattern has the following consequences:
- Decoupling of producers from consumers. There are no compile time dependencies between the two types of object.
- Improved extensiblity. Adding new message types, producers or consumers could not be easier.
- Multi-thread Safety. Use a mutex to restrict access to the queue and producers can run in a separate thread to the consumers.
Implementation
Consider the following when implementing the Router pattern:
- Should there be only one Router object? Many Routers could be used to provide queues of different priorities but the implementation is necessarily further complicated.
- Multi-thread Safety. The simplest multi-threaded model is to run all the consumers in a single thread whilst the producers can run in many different threads. If, however, the consumers are to run in different threads, a deep copy of the message object should be created for each consumer.
- Performance Associative containers (like the STL's map or MFC's CMap) should be used to encapsulate the relations between Router and Route, and Route and Consumer in order to provide the performance and scalability required for selection, addition and iteration. Suitable hashing algorithms should be devised to prevent excessive memory usage.
- Individual Message Handlers The pattern currently specifies that Consumers provide a single function to handle all messages. A relatively simple modification would enable consumers to register handler functions for each type of message.
Sample Code
The following code snippets make use of the STL templates:
Related Patterns
Smalltalk's Model/View/Controller pattern and MFC's Document/View paradigm provide similar functionality but in a more restrictive, GUI centric manner.
