3

Suppose I have a baseclass called IMessage, and lots of derived message classes.

In my program I have one method that receives all messages :

void ReceiveMessage(IMessage message)
{
}

and I'd like to call a specific method for each type of message. It would be great if I could do :

void ReceiveMessage(IMessage message)
{
    HandleMessage(message);
}

void HandleMessage(DummyMessage message)
{
    Blah;
}

void HandleMessage(SillyMessage message)
{
    Yuk;
}

..but apparently "we ain't going out like that".

So how would I go about implementing specific handlers for specific messages, being called from a single messagehandler ?

Pygmy
  • 1,268
  • 17
  • 33
  • 1
    Shouldn't the IMessage interface define the 'common' method(s) which all implementations of IMessage implement which would allow you to just call those methods in your ReceiveMessage method? – Trevor Pilley Mar 24 '12 at 00:21
  • @TrevorPilley It depends. There are times when that's not appropriate. Many game engines or 3D scene graphs, for example, will have situations where each scene type (message) gets very different handling by different "actors" within the scene. – Reed Copsey Mar 24 '12 at 00:28
  • I want the handler to be called in another class, not in the message itself... (For example, a Server class would be expected to contain all the handlers for different messages) – Pygmy Mar 24 '12 at 00:30

4 Answers4

4

The classic way to handle this type of situation is via the Visitor pattern.

That being said, you can actually handle this a bit easier in C# via dynamic, like so:

void ReceiveMessage(IMessage message)
{
    dynamic specificMessage = message;
    this.HandleMessage(specificMessage):
}

The dynamic binding engine will find, at runtime, the "best" match for your specific message type, and route the call to the appropriate method.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
1

Your IMessage interface should have a HandleMessage() function defined that each type implements:

public interface IMessage
{
    void HandleMessage();
}

public class DummyMessage : IMessage
{
     public void HandleMessage()
     {
         Blah;
     }
}

public class SillyMessage : IMessage
{
     public void HandleMessage()
     {
         Yak;
     }
}

Then you would call it like this:

void ReceiveMessage(IMessage message)
{
    message.HandleMessage();
}
Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
  • This doesn't work if multiple receivers need to treat individual message types differently. The Visitor pattern is the classic way to handle this type of scenario, in that case. – Reed Copsey Mar 24 '12 at 00:26
0

Try using a factory method. Look up factory design pattern.

kasavbere
  • 5,873
  • 14
  • 49
  • 72
0

It is possible to do what you're suggesting, though it's not very DRY, and I think the other suggestions here are more appropriate. Still, in the interest of completeness, here's an approach close to what you were originally looking for:

void ReceiveMessage( IMessage message ) {
  if( message as DummyMessage != null ) HandleMessage( message as DummyMessage );
  else if( message as SillyMessage != null ) HandleMessage( message as SillyMessage );
  // etc
}
Ethan Brown
  • 26,892
  • 4
  • 80
  • 92