用于处理多种消息类型,设计模式 [英] Design pattern for handling multiple message types

查看:1211
本文介绍了用于处理多种消息类型,设计模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经得到了GOF坐在这里我的办公桌上,我知道一定有某种能解决我遇到的问题的设计模式,而人我不明白。

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.

有关的纯朴的缘故,我已经改变了一些接口,我使用的名称。

For simplicities sake, I've changed the name of some of the interfaces that I'm using.

因此​​,这里的问题,对丝的一面,我有一个发出不同类型的消息的多台服务器。在电线的另一侧我有需要能够处理各种不同类型的消息的客户端。

So here's the problem, on one side of the wire, I've got multiple servers that send out different types of messages. On the other side of the wire I have a client that needs to be able to handle all the different types of messages.

所有的信息实现相同的通用界面即时聊天。我的问题是,当客户端获得一个新的消息对象,它是如何知道什么类型的即时聊天的其接收的?

All messages implement the same common interface IMessage. My problem is, when the client gets a new IMessage, how does it know what type of IMessage its received?

我认为我可以做类似以下,但这只是觉得可怕。

I supposed I could do something like the following, but this just FEELS awful.

TradeMessage tMessage = newMessage as TradeMessage;
if (tMessage != null)
{
    ProcessTradeMessage(tMessage);
}

OrderMessage oMessage = newMessage as OrderMessage;
if (oMessage != null)
{
    ProcessOrderMessage(oMessage);
}

第二个想法,就是增加一个属性,以即时聊天称为MessageTypeID,但这需要我写类似以下,这也感到可怕的。

The second thought, is to add a property to IMessage called MessageTypeID, but that would require me to write something like the following, which also FEELS awful.

TradeMessage tMessage = new TradeMessage();
if (newMessage.MessageTypeID == tMessage.MessageTypeID)
{
    tMessage = newMessage as TradeMessage;
    ProcessTradeMessage(tMessage); 
}

OrderMessage oMessage = new OrderMessage();
if (newMessage.MessageTypeID == oMessage.MessageTypeID)
{
    oMessage = newMessage as OrderMessage;
    ProcessOrderMessage(oMessage);
}

我知道这个普遍的问题已经解决了一百万次,所以必须有解决具有需要一个接口作为参数的方法问题的一个更好的方式,但需要根据已实施哪些类不同的流量控制该接口。

I know this general problem has been tackled a million times, so there has to be a nicer way of solving the problem of having a method that takes an interface as a parameter, but needs different flow control based on what class has implemented that interface.

推荐答案

您可以为每种消息类型创建单独的消息处理程序,并天真地将消息传递到每一个可用的处理程序,除非你找到一个可以处理它。类似的责任链模式:

You could create separate message handlers for each message type, and naively pass the message to each available handler until you find one that can handle it. Similar to the chain of responsibility pattern:

public interface IMessageHandler {
    bool HandleMessage( IMessage msg );
}

public class OrderMessageHandler {
    bool HandleMessage( IMessage msg ) {
       if ( !msg is OrderMessage) return false;

       // Handle the message.
    }
}

public class SomeOtherMessageHandler {
    bool HandleMessage( IMessage msg ) {
       if ( !msg is SomeOtherMessage ) return false;

       // Handle the message.
    }
}

... etc ...

public class MessageProcessor {
    private List<IMessageHandler> handlers;

    public MessageProcessor() {
       handlers = new List<IMessageHandler>();
       handlers.add(new SomeOtherMessageHandler());
       handlers.add(new OrderMessageHandler());
    }

    public void ProcessMessage( IMessage msg ) {
       bool messageWasHandled
       foreach( IMessageHandler handler in handlers ) {
           if ( handler.HandleMessage(msg) ) {
               messageWasHandled = true;
               break;
           }
       }

       if ( !messageWasHandled ) {
          // Do some default processing, throw error, whatever.
       }
    }
}

您也可以实现这个作为地图,与消息类名或消息类型ID作为重点和相应的处理程序实例作为值。

You could also implement this as a map, with the message class name or message type id as a key and the appropriate handler instance as the value.

也有人建议有消息对象的把手本身,但只是感觉不对我。看起来这将是最好的消息的处理从消息本身分开。

Others have suggested having the message object "handle" itself, but that just doesn't feel right to me. Seems like it would be best to separate the handling of the message from the message itself.

其他的有些事情,我喜欢它:

Some other things I like about it:


  1. 您可以通过注入或弹簧消息处理程序是什么具备的,你,而不是在构造函数中创建它们,使这个非常检验的。

  1. You can inject the message handlers via spring or what-have-you rather than creating them in the constructor, making this very testable.

您可以通过简单地从ProcessMessage的循环删除破发推出主题类似的行为,你有一条消息多个处理程序。

You can introduce topic-like behavior where you have multiple handlers for a single message by simply removing the "break" from the ProcessMessage loop.

通过从处理分隔邮件,你可以在不同的目的地相同的消息不同的处理(处理相同的消息例如,多个班级的MessageProcessor不同)

By separating the message from the handler, you can have different handlers for the same message at different destinations (e.g. multiple MessageProcessor classes that handle the same messages differently)

这篇关于用于处理多种消息类型,设计模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆