Meine Zustandsmaschine der obersten Ebene hat einige Zustände und Kanten. Ich werde dies die übergeordnete Zustandsmaschine nennen.
A ----> B ----> C
Jeder Zustand innerhalb der übergeordneten Zustandsmaschine kann auch eine Zustandsmaschine sein. Ich werde diese Kinder als Staatsmaschinen bezeichnen.
___________
/ \
A ----> | B0->B1->B2 | ----> C
\____________/
Wenn die übergeordnete Zustandsmaschine von A nach B übergeht, übernimmt die Zustandsmaschine von B. Wie sollte B nach dem Ausführen die Kontrolle an die übergeordnete Zustandsmaschine abgeben und in den Zustand C übergehen? Welches Designmuster verwenden Sie?
Wenn Sie sich fragen, habe ich untergeordnete Zustandsautomaten in übergeordneten Zustandsautomaten, da mein genaues Projekt ziemlich komplex ist und es natürlich ist, die internen Abläufe eines untergeordneten Zustands zu kapseln.
MachineContainer
Klasse habenB
, die B0, B1 und B2 enthält, und wenn B2 endet, gibt sie die Kontrolle an ihren Container zurück, der dann zu C übergeht ... Ich habe so etwas jedoch noch nie versucht. Es ist ein interessantes Problem!Antworten:
Jede Zustandsmaschine verfügt über eine Art Ereignishandler und ein Mittel zum Auslösen dieser Ereignisse. Dieser Handler nimmt den vorhandenen Status und die Art des Ereignisses als Eingabe, wählt den neuen Status aus und führt optional einen Nebenwirkungscode aus.
Im Wesentlichen
B
leitet Ihr Hauptereignishandler im Status alle Ereignisse, die er nicht erkennt, anB
den Ereignishandler weiter und bleibt im StatusB
. Wenn SieB
zu wechselnC
möchten, wird das entsprechende Ereignis an den Hauptereignishandler gesendet.quelle
Hast du diesen Abschnitt von Taoup gelesen ? Es gibt verschiedene Möglichkeiten, dies zu erreichen, aber viele davon hängen davon ab, wie Sie Ihre Zustandsautomaten aufgeteilt haben. Sind sie getrennte Prozesse? Themen? Objekte?
Finden Sie heraus, wie Sie sie gebaut haben, und prüfen Sie, ob es eine kanonische Art der Kommunikation gibt. Wenn eines nicht vorhanden ist, entwerfen Sie Ihr System möglicherweise falsch.
Für mich würde ich getrennte Prozesse betrachten und stdin und stdout miteinander verbinden. Die untergeordnete Zustandsmaschine wird dann eigenständig, wirkt auf stdin und gibt auf stdout aus. Es wird zur Aufgabe der übergeordneten Zustandsmaschine, den untergeordneten Prozess zu starten, die Pipes anzuschließen, dann Daten einzugeben und auf Ergebnisse zu warten. All diese Dinge wurden bereits in allen modernen Sprachen erledigt, daher sollte es einfach sein, dies zu tun.
quelle
Trennen Sie die beiden Zustandsautomaten und verwenden Sie die Nachrichtenübertragung zwischen ihnen. Somit würde die Zustandsmaschine 1 von ABC ausgehen, wo sie im Zustand B nach den aktuellen Ergebnissen von der Zustandsmaschine 2 sucht. Wenn sich die Ausgabe geändert hat, kann die Zustandsmaschine 1 dies berücksichtigen und die Zustandsmaschine 2 muss keine Kenntnis haben wie Zustandsmaschine 1 tatsächlich funktioniert. So etwas wie:
quelle
Die Lösung hängt davon ab, 1) ob die Unterzustände von A für die Unterzustände von B sichtbar sind. 2) Leiten AB und C von einem gemeinsamen Elternteil ab? Wenn sie ein gemeinsames Elternteil haben und die Sichtbarkeit universell ist, sollten Sie nicht zu viel Mühe haben, vom Unterzustand von B in den Unterzustand von A zu wechseln.
Wenn Sie sie über Namespaces isoliert haben und / oder A, B und C keine gemeinsamen Eltern haben, ist es am besten, einen externen Treiber für Statusänderungen für A-, B- und C-Maschinen zu haben. Dies kann über einen Event-Handler erfolgen. Haben Sie einfach einen Beobachter in A, der Ereignisse in B abhören und basierend auf dem Ereignis in einen eigenen Unterzustand übergehen kann.
quelle