我正在使用简单的二进制协议。每个数据包由10个字节组成。第一个字节指定数据包类型。有许多(〜50)数据包类型使用。在Java中分离协议解析器和处理程序
我想为这个协议编写一个独立于数据包处理的通用解析器。所以解析器应该检测数据包类型并将数据放入适当数据包类的实例中,该类包含协议数据。例如,考虑以下类别:解析器检测到数据包类型1 - >新的Type1()并读取原始字节并设置温度和湿度。对于数据包类型2和所有其他数据包类型也是如此。
class Packet {
byte[] raw;
}
class Type1 extends Packet {
int temperature;
int humidity;
}
class Type2 extends Packet {
DateTime sunrise;
DateTime sunset;
}
既然有这么多的数据包类型,但每个应用程序只使用很少的,它应该是可能的分析开始之前对某些类型的注册。所有其他数据包类型都被忽略。
我打算为每个数据包类型分配一个PacketParser。也许,我需要每种类型的处理程序类。例如:
abstract class Type1Parser {
abstract void handle(Type1 packet);
}
class Type1Parser extends PacketParser {
//how to use/set handler? how to pass packet to handler?
static public Type1Handler type1Handler = null;
@override
void parse(Packet input) {
if(type1Handler == null)
return;
Type1 packet = new Type1(input);
packet.temperature = byteToInt(input.raw, 0, 3);
packet.humidity = byteToInt(input.raw, 4, 7);
type1Handler.handle(packet);
}
}
如何连接解析器和处理程序?高于天真的方法: 程序需要实现Type1Handler并设置静态变量Type1Parser.type1Handler。
然后主分析器可以是这样的:
class MainParser {
Type1Parser type1 = new Type1Parser();
Type2Parser type2 = new Type2Parser();
...
void parse(byte[] packet) {
switch(packet[0]) {
case 1: type1.parse(packet); break;
case 2: type2.parse(packet); break;
...
}
}
}
然而,这似乎是1)有很多的代码2)大量的开销非常类似的路线,因为所有的数据包解析器被实例化和对于每个数据包,调用parse(),即使没有注册处理程序。
任何想法如何改善此代码?
注意:解析应该对程序透明。解析代码应该留在“解析库”中。所以理想情况下,程序只“知道”类TypeXHandler和TypeX。
“对于每个数据包parse()被调用,即使没有注册处理程序”。 - 似乎有必要调用解析器,至少在输入流中跳过数据包的字节。您可以读取数据包类型并跳过剩余的解析,只需跳过数据包长度(我假设每个数据包类型都具有固定长度)。 –
处理程序是您想要将数据包信息传递给哪个代码的部分?它应该做什么? – NESPowerGlove
为了摆脱* parse中的* some *重复,你可以不用'PacketParser解析器;'使用开关来确定和设置解析器,然后在开关外侧执行'parser.parse(packet);'?我知道这并不深刻,但确实减少了逐字。 – ChiefTwoPencils