Implementieren des Kommunikationsprotokolls in Java mithilfe des Zustandsmusterdesigns

Entschuldigung, wenn dies anderswo beantwortet wird; Ich konnte nicht genug Informationen finden, um mich davon zu überzeugen, wie das am besten funktioniert. Mir ist auch klar, dass dies eine lange Erklärung ohne Code ist, aber lassen Sie mich wissen, ob ich einen Beispielcode erstellen sollte, um zu demonstrieren, was ich tue.

Grundsätzlich gilt:

Implementierung eines Kommunikationsprotokolls in Java mit System.in/outDerzeit wird ein Statusmuster implementiert, bei dem ein Scanner in der Kontextklasse auf System.in instanziiert wirdKonkrete Zustände rufen eine Kontextmethode zum Lesen vom Scanner auf und führen anschließend Aktionen / Übergangszustände entsprechend dem vom Scanner zurückgegebenen Wert aus

Meine ursprüngliche Absicht für die Verwendung eines Statusmusters war es, den Code beim Parsen von Sequenzen wie dieser aus System.in zu vereinfachen (fragen Sie nicht nach der Syntax, ich muss damit arbeiten):

BEFEHLSNAME = XHEADERKopfzeile InformationenINHALTBefehlszeilen InhaltENDEINHALTENDCOMMAND

Ich definiere im Allgemeinen einen konkreten Status für jeden Befehlstyp, den ich erwarten würde. Anhand der obigen Sequenz hätte ich einen Statussatz, der ungefähr so ​​aussah wie {WAITING_FOR_COMMAND, COMMAND_RECEIVED, PARSING_HEADER, PARSING_CONTENTS, PARSING_DONE, COMMAND_PROCESSED}. Ich würde anfangs in WAITING_FOR_COMMAND sein, dann, wenn "COMMAND NAME = X" empfangen wird, würde ich zu COMMAND_RECEIVED übergehen, dann, wenn "HEADER" hereinkommt, würde ich zu PARSING_HEADER übergehen, usw. Dieser Entwurf macht das Überqueren aller Kantenfälle in Das Protokoll ist einfacher und der Code kann auch einfach aktualisiert / gewartet werden, wenn das Protokoll optimiert wird. Offensichtlich viel besser als massive Schalteranweisungen und wiederholte Grenzüberprüfungen.

Das Problem, das ich habe, ist, dass ich immer mehr Zustandsvariablen in der Kontextklasse deklariere, während ich mein konkretes Zustandsverhalten ausarbeite, und weiß, dass dies wahrscheinlich schlecht ist, da ich sehr exponierte Schnittstellen und sehr hohe Verknüpfungen zwischen den Variablen erstelle Kontext und konkrete Zustandsklassen. Die Befehlssequenzen in diesem Protokoll können beliebig lang sein, und ich muss die von jedem Element in der Befehlssequenz übermittelten Informationen speichern, bis die Befehlssequenz abgeschlossen ist.

Am Beispiel der obigen Befehlssequenz möchte ich nach "COMMAND ID = X" den Wert X für die zukünftige Verwendung speichern, nachdem ich "ENDCOMMAND" erhalten und den Befehl vollständig verarbeitet habe. Nach "HEADER" möchte ich die Header-Informationen für die zukünftige Verwendung speichern, nachdem ich "ENDCOMMAND" für die tatsächliche Verarbeitung des Befehls erhalten habe. Und so weiter und so fort. Das Hinzufügen von commandId- und Header-Statusvariablen zur Context-Klasse funktioniert im Moment, scheint mir aber überhaupt nicht sauber oder gut gekapselt zu sein.

Hat jemand Vorschläge auf hoher Ebene, wie er dieses Problem angehen würde? Gibt es eine bessere Verwendung eines Zustandsentwurfsmusters dafür?

Nur um einige Ideen zu erwähnen, mit denen ich gespielt habe:

Definieren von Zustandskontexten für jeden Typ von Befehlssequenz und Aufrufen des geeigneten Kontextes beim Empfang des relevanten Befehls von System.in; dies scheint fast so chaotisch zu sein wie riesige Schalterblöcke und scheint das Design übermäßig zu verwirrenEntwerfen einer vollständigen FSM-Architektur, die zusammengesetzte FSMs unterstützt, wobei jede Befehlssequenz einen eigenen FSM in einem übergeordneten FSM belegt; Das scheint mir übertriebenErstellen eines ProtocolCommand-Objekts mit verschiedenen Unterklassen für jeden Befehlssequenztyp; Ich könnte diese beim Übergang in jeden Zustand übergeben und sie nach und nach aufbauen, aber dies überfrachtet die Zustandsschnittstelle und zwingt alle Zustände, einen Parameter aufzunehmen, den sie nicht unbedingt verwenden

Vielen Dank! Entschuldigung, das war so ausführlich, lass es mich wissen, wenn ich etwas klarstellen kann.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage