I\'ve got the GOF sitting on my desk here and I know there must be some kind of design pattern that solves the problem I\'m having, but man I can\'t figure it out.
F
From my experience with message handling, its usually the case that different consumers of messages require handling a variety of message types. I found the Double Dispatch pattern to handle this nicely. The basic idea is to register a set of handlers that dispatch the received messages to the handler for processing based on the specific type (using function overloading). The consumers only register for the specific types they wish to receive. Below is a class diagram.

The code looks like this:
IHandler
public interface IHandler
{
}
IMessageHandler
public interface IMessageHandler : IHandler
{
void ProcessMessage(MessageType message);
}
IMessage
public interface IMessage
{
void Dispatch(IHandler handler);
}
MessageBase
public class MessageBase : IMessage
where MessageType : class, IMessage
{
public void Dispatch(IHandler handler)
{
MessageType msg_as_msg_type = this as MessageType;
if (msg_as_msg_type != null)
{
DynamicDispatch(handler, msg_as_msg_type);
}
}
protected void DynamicDispatch(IHandler handler, MessageType self)
{
IMessageHandler handlerTarget =
handler as IMessageHandler;
if (handlerTarget != null)
{
handlerTarget.ProcessMessage(self);
}
}
}
DerivedMessageHandlerOne
// Consumer of DerivedMessageOne and DerivedMessageTwo
// (some task or process that wants to receive messages)
public class DerivedMessageHandlerOne :
IMessageHandler,
IMessageHandler
// Just add handlers here to process incoming messages
{
public DerivedMessageHandlerOne() { }
#region IMessageHandler Members
// ************ handle both messages *************** //
public void ProcessMessage(DerivedMessageOne message)
{
// Received Message one, do something with it
}
public void ProcessMessage(DerivedMessageTwo message)
{
// Received Message two, do something with it
}
#endregion
}
DerivedMessageOne
public class DerivedMessageOne : MessageBase
{
public int MessageOneField;
public DerivedMessageOne() { }
}
Then you just have a container that manages the Handlers and you are all set. A simple for loop through the list of Handlers when a message received, and the Handlers receive the messages where they want them
// Receive some message and dispatch it to listeners
IMessage message_received = ...
foreach(IHandler handler in mListOfRegisteredHandlers)
{
message_received.Dispatch(handler);
}
This design came out of a question I asked awhile back about Polymorphic Event Handling