Message Handling Without Dependencies
by Anthony Williams

Listing One

void handleMessage(Message* message)
{
    if(Message1* m=dynamic_cast<Message1*>(message))
    {
        handleMessage1(m);
    }
    else if(Message2* m=dynamic_cast<Message2*>(message))
    {
        handleMessage2(m);
    }
    // ...
}


Listing Two

class Message
{
public:
    virtual void dispatch(MessageHandler* handler)=0;
};
class Message1:
    public Message
{
    void dispatch(MessageHandler* handler)
    {
        handler->process(this);
    }
};
class Message2:
    public Message
{
    void dispatch(MessageHandler* handler)
    {
        handler->process(this);
    }
};
// other message classes
class MessageHandler
{
    void process(Message1*);
    void process(Message2*);
    // overloads of process for other messages
};


Listing Three

class MessageHandler
{
    virtual void process(Message1*)=0;
    virtual void process(Message2*)=0;
    virtual void process(Message3*)=0;
    virtual void process(Message4*)=0;
    // overloads of process for other messages
};
class SpecificMessageHandler:
    public MessageHandler
{
    void process(Message1*);
    void process(Message2*);
    void process(Message3*);
    void process(Message4*);
    // overloads of process for other messages
};
class OtherSpecificMessageHandler:
    public MessageHandler
{
    void process(Message1*);
    void process(Message2*);
    void process(Message3*);
    void process(Message4*);
    // overloads of process for other messages
};


Listing Four

class MessageHandlerBase
{};
class Message1HandlerBase:
    public virtual MessageHandlerBase
{
    virtual void process(Message1*)=0;
};
class Message1
{
    void dispatch(MessageHandlerBase* handler)
    {
        dynamic_cast<Message1HandlerBase&>(*handler).process(this);
    }
};
class Message2HandlerBase:
    public virtual MessageHandlerBase
{
    virtual void process(Message2*)=0;
};
class Message2:
    public MessageBase
{
    void dispatch(MessageHandlerBase* handler)
    {
        dynamic_cast<Message2HandlerBase&>(*handler).process(this);
    }
};
// ...
class SpecificMessageHandler:
    public Message1HandlerBase,
    public Message2HandlerBase
{
    void process(Message1*);
    void process(Message2*);
};
class OtherSpecificMessageHandler:
    public Message3HandlerBase,
    public Message4HandlerBase
{
    void process(Message3*);
    void process(Message4*);
};


Listing Five

template<typename MessageType>
class MessageHandler:
    public virtual MessageHandlerBase
{
    virtual void process(MessageType*)=0;
};
class Message1
{
    void dispatch(MessageHandlerBase* handler)
    {
        dynamic_cast<MessageHandler<Message1>&>(*handler).process(this);
    }
};
class SpecificMessageHandler:
    public MessageHandler<Message1>,
    public MessageHandler<Message2>
{
    void process(Message1*);
    void process(Message2*);
};


Listing Six

class Message
{
protected:
    template<typename MessageType>
    void dynamicDispatch(MessageHandlerBase* handler,MessageType* self)
    {
        dynamic_cast<MessageHandler<MessageType>&>(*handler).process(self);
    }
};
class Message1:
    public MessageBase
{
    void dispatch(MessageHandlerBase* handler)
    {
        dynamicDispatch(handler,this);
    }
};




