Je travaille avec un protocole binaire simple. Chaque paquet est composé de 10 octets. Le premier octet spécifie le type de paquet. Il y a beaucoup (environ 50) types de paquets utilisés.Séparer l'analyseur de protocole et le gestionnaire en Java
Je veux écrire un analyseur général pour ce protocole qui est indépendant de la gestion des paquets. L'analyseur doit donc détecter le type de paquet et placer les données dans une instance de la classe de paquets appropriée, qui contient les données de protocole. Par exemple, en considérant les classes ci-dessous: Lorsque l'analyseur détecte le type de paquet 1 -> new Type1() et lit les octets bruts et définit la température et l'humidité. De même pour le type de paquet 2 et tous les autres types de paquets.
class Packet {
byte[] raw;
}
class Type1 extends Packet {
int temperature;
int humidity;
}
class Type2 extends Packet {
DateTime sunrise;
DateTime sunset;
}
Comme il y a tant de types de paquets, mais chaque application utilise que très peu, il devrait être possible d'enregistrer pour certains types avant l'analyse commence. Tous les autres types de paquets sont ignorés.
Je prévois d'avoir un PacketParser pour chaque type de paquet. Probablement, j'ai besoin d'un cours de handler pour chaque type aussi. E.g .:
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);
}
}
Comment se connecter parser et handler? Au-dessus d'une approche naïve: Le programme doit implémenter Type1Handler et définir la variable statique Type1Parser.type1Handler.
Ensuite, l'analyseur principal peut ressembler à ceci:
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;
...
}
}
}
Cependant, cela semble être 1) un grand nombre de lignes très similaires de code 2) beaucoup de frais généraux, puisque tout analyseur de paquets sont instanciés et pour chaque paquet parse() est appelé, même si aucun gestionnaire n'est enregistré.
Des idées pour améliorer ce code?
Remarque: L'analyse doit être transparente pour le programme. Le code d'analyse doit rester dans la "bibliothèque d'analyse". Donc idéalement, le programme ne "connaît" que les classes TypeXHandler et TypeX.
"pour chaque paquet analysé() est appelé, même si aucun gestionnaire n'est enregistré." - semble être nécessaire d'appeler un analyseur, au moins, pour sauter les octets des paquets dans le flux d'entrée. Vous pouvez lire le type de paquet et ignorer le reste de l'analyse en sautant simplement la longueur du paquet (j'ai supposé que chaque type de paquet avait une longueur fixe). –
Est-ce que le gestionnaire de la partie de code que vous souhaitez transmettre les informations de paquet à? Qu'est-ce que c'est supposé faire? – NESPowerGlove
Pour se débarrasser de la répétition de * some * dans 'parse', ne pouvez-vous pas faire l'analyseur' PacketParser '? Utilisez le commutateur pour déterminer et définir l'analyseur, puis sur le commutateur 'parser.parse (paquet);'? Je sais que ce n'est pas profond mais réduit le verbatim. – ChiefTwoPencils