Ich arbeite mit einem einfachen, binären Protokoll. Jedes Paket besteht aus 10 Bytes. Das erste Byte gibt den Pakettyp an. Es werden viele (~ 50) Pakettypen verwendet.Protokoll-Parser und Handler in Java trennen
Ich möchte einen allgemeinen Parser für dieses Protokoll schreiben, das unabhängig von der Behandlung von Paketen ist. Daher sollte der Parser den Pakettyp erkennen und die Daten in eine Instanz der entsprechenden Paketklasse einfügen, die die Protokolldaten enthält. Z. B. unter Berücksichtigung der folgenden Klassen: Wenn der Parser den Pakettyp 1 -> neuen Typ 1() erkennt und Rohbytes liest und Temperatur und Feuchtigkeit einstellt. Ähnlich für Pakettyp 2 und alle anderen Pakettypen.
class Packet {
byte[] raw;
}
class Type1 extends Packet {
int temperature;
int humidity;
}
class Type2 extends Packet {
DateTime sunrise;
DateTime sunset;
}
Da es so viele Pakettypen sind aber jede Anwendung verwendet nur sehr wenige, sollte es möglich sein, für bestimmte Arten zu registrieren, bevor beginnt das Parsen. Alle anderen Pakettypen werden ignoriert.
Ich plane, einen PacketParser für jeden Pakettyp zu haben. Wahrscheinlich brauche ich auch eine Handler-Klasse für jeden Typ. Z.B .:
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);
}
}
Wie Parser und Handler verbinden? Über einem naiven Ansatz: Das Programm muss Type1Handler implementieren und die statische Variable Type1Parser.type1Handler festlegen.
Dann kann der Haupt-Parser wie folgt aussehen:
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;
...
}
}
}
Dies scheint jedoch 1) zu sein, viele sehr ähnliche Zeilen Code 2) eine Menge Aufwand, da alle Paketparser instanziiert und Für jedes Paket wird parse() aufgerufen, auch wenn kein Handler registriert ist.
Haben Sie Ideen, wie Sie diesen Code verbessern können?
Hinweis: Das Parsing sollte für das Programm transparent sein. Parsing-Code sollte in der "Parsing-Bibliothek" bleiben. Im Idealfall "kennt" das Programm also nur die Klassen TypeXHandler und TypeX.
"für jedes Paket wird parse() aufgerufen, auch wenn kein Handler registriert ist." - Es scheint notwendig zu sein, mindestens einen Parser aufzurufen, um die Bytes der Pakete im Eingangsstrom zu überspringen. Sie können den Pakettyp lesen und den Rest des Parsings überspringen, indem Sie einfach die Paketlänge überspringen (ich nahm an, dass jeder Pakettyp eine feste Länge hat). –
Handler ist der Teil des Codes, an den Sie die Paketinformation weitergeben möchten? Was soll es tun? – NESPowerGlove
Um * einige * Wiederholungen in 'Parse 'loszuwerden, können Sie' PacketParser Parser' nicht verwenden. Verwenden Sie den Schalter, um den Parser zu bestimmen und zu setzen, und wechseln Sie dann den Schalter 'parser.parse (packet);'? Ich weiß, dass es nicht tiefgründig ist, aber es reduziert das Wort. – ChiefTwoPencils