Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 设计多个消息类型,但子类都做相同的事情_Java - Fatal编程技术网

Java 设计多个消息类型,但子类都做相同的事情

Java 设计多个消息类型,但子类都做相同的事情,java,Java,我看了这个问题的答案: 我也在一条类似的船上。不同之处在于,我使用的是一个现有的protobuf模式,我无法更改。protobuf架构没有messageType属性。生成的代码如下所示 TradeMessage.parseFrom(byte[] bytes) OtherMessage.parseFrom(byte[] bytes) AnotherMessage.parseFrom(byte[] bytes) 所以现在我有一个工厂模式,当一条消息进入接收器时 MessageReceiver.ja

我看了这个问题的答案:

我也在一条类似的船上。不同之处在于,我使用的是一个现有的protobuf模式,我无法更改。protobuf架构没有messageType属性。生成的代码如下所示

TradeMessage.parseFrom(byte[] bytes)
OtherMessage.parseFrom(byte[] bytes)
AnotherMessage.parseFrom(byte[] bytes)
所以现在我有一个工厂模式,当一条消息进入接收器时

MessageReceiver.java

Object parser = messageParserFactory.getParser(messageType);
获取解析器的类型

MessageParserFactory.java

public MessageParser getParser(int messageType) {
    if (messageType = Constants.TRADE_MESSAGE) {
        return new TradeParser();
    } else if (messageType = Constants.OTHER_MESSAGE) {
        return new OtherParser();
    }
    return null;
}
对于所有不同的消息类型,基本上都是重复的工作,这些消息类型基本上只是包装生成的parseFrom方法

public interface MessageParser {
    void doParse(byte[] bytes);
}

TradeParser.java
public void doParse(byte[] bytes) {
    TradeParser.parseFrom(bytes);
}

OtherParser.java
public void doParse(byte[] bytes) {
    OtherParser.parseFrom(bytes);
}

AnotherParser.java
public void doParse(byte[] bytes) {
    AnotherParser.parseFrom(bytes);
}

它可以工作,但有没有更好的方法,因为基本上我为每种消息类型创建的所有解析器都做完全相同的事情,只需调用
parseFrom

你会有大量的消息类型吗?你的信息复杂吗

在任何情况下,我明白了为什么您可能认为这是不必要的,因为您目前正在包装parseFrom方法。如果您的解析变得复杂,而不仅仅是调用parseFrom方法,那么它可能会变得有趣

public interface MessageParser {
    void doParse(byte[] bytes);
}

TradeParser.java
public void doParse(byte[] bytes) {
    TradeParser.parseFrom(bytes);
}

OtherParser.java
public void doParse(byte[] bytes) {
    OtherParser.parseFrom(bytes);
}

AnotherParser.java
public void doParse(byte[] bytes) {
    AnotherParser.parseFrom(bytes);
}
目前,存储一个键值数组,messageType作为key,Class作为value,然后使用反射来实例化消息,这不是最好的做法吗


我认为这可能相当干净,因为您可以在context/config文件中定义数组。

消息类型的数量将少于20。除了解析消息,我看不到解析器中有多少逻辑。逻辑在应用程序的另一个领域。我如何使用反射来实现这一点?是否存在任何性能成本,因为每次从客户机传入消息时,它都必须向下移动才能获得messageParser。是的,通过反射实例化会有很大的性能成本。然而,我假设您的parseFrom方法可能是静态的,并且我相信对静态方法的调用比较便宜。不会记住来源,所以请谨慎使用此语句,或者更好,测试它!在逻辑中,您必须查看数组,获取与消息类型关联的类,然后使用反射调用parseFrom。它类似于:methodm=clazz.getMethod(“name”,argTypes);objecto=method.invoke(null,args);您需要
MessageParser
吗?为什么不直接返回已解析的实例?
messageType=
应该是
messageType=
。我认为这只是一种伪代码?另外,不要返回
null
,如果它是不受支持的消息类型,则抛出一个异常。@AndyTurner不,我根本不需要消息解析器。这只是为了理顺客户的主要切入点。实际上,我可以为消息类型使用一个switch语句,然后返回解析后的对象。@michaelya只是所有的伪代码。谢谢。