Design pattern for handling multiple message types

前端 未结 10 1076
甜味超标
甜味超标 2020-11-28 03:13

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

10条回答
  •  旧时难觅i
    2020-11-28 03:58

    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.

    Double Dispatch UML 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

提交回复
热议问题