我正在使用簡單的二進制協議。每個數據包由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