Akka Java FSM mit Beispiel

9

Bitte beachten Sie: Ich bin ein Java-Entwickler ohne Scala-Kenntnisse (leider). Ich würde verlangen, dass jedes Codebeispiel, das in der Antwort zur Verfügung gestellt wird, Akka's Java API verwendet.

Ich versuche, die Akka FSM API zu verwenden, um die folgende super-einfache Zustandsmaschine zu modellieren. In Wirklichkeit ist meine Maschine viel komplizierter, aber die Antwort auf diese Frage erlaubt mir, auf meine tatsächliche FSM zu extrapolieren.

Und ich habe 2 Zustände: Off und On . Sie können von Off -> On wechseln, indem Sie den Computer einschalten, indem Sie SomeObject#powerOn(<someArguments>) aufrufen. Sie können von On -> Off wechseln, indem Sie den Computer ausschalten, indem Sie SomeObject#powerOff(<someArguments>) aufrufen.

Ich frage mich, welche Schauspieler und unterstützenden Klassen ich brauche, um diese FSM zu implementieren. Ich glaube der Akteur, der die FSM repräsentiert, muss AbstractFSM erweitern. Aber welche Klassen repräsentieren die 2 Staaten? Mit welchem ​​Code werden die Zustandsübergänge powerOn(...) und powerOff(...) angezeigt und implementiert? Ein funktionierendes Java-Beispiel oder auch nur Java-Pseudocode würde hier einen langen Weg zurücklegen.

    
smeeb 16.06.2015, 01:34
quelle

2 Antworten

19

Ich denke, wir können etwas besser als Copypasta aus den FSM-Dokumenten ( Ссылка <) / a>). Lassen Sie uns zuerst Ihren Anwendungsfall näher untersuchen.

Sie haben zwei Trigger (oder Ereignisse oder Signale) - powerOn und powerOff. Sie möchten diese Signale an einen Actor senden und den Status wechseln lassen, von dem die beiden bedeutungsvollen Zustände On und Off sind.

Genau genommen braucht ein FSM genau eine zusätzliche Komponente: eine Aktion, die Sie beim Übergang durchführen möchten.

%Vor%

Sie tun nicht NEED eine Aktion, aber ein Actor kann nicht direkt überprüft oder direkt geändert werden. Alle Mutationen und Bestätigungen erfolgen durch asynchrone Nachrichtenweitergabe.

In Ihrem Beispiel, das keine Aktion für den Übergang vorsieht, haben Sie im Grunde eine Zustandsmaschine, die keine Operation ist. Es treten Aktionen auf, Zustandsübergänge ohne Nebenwirkung und dieser Zustand ist unsichtbar, also ist eine Arbeitsmaschine identisch mit einer Gebrochenen. Und da dies alles asynchron geschieht, wissen Sie nicht einmal, wann das kaputte Ding fertig ist.

Erlauben Sie mir also, Ihren Vertrag ein wenig zu erweitern und die folgenden Aktionen in Ihre FSM-Definitionen aufzunehmen:

%Vor%

Jetzt können wir vielleicht eine FSM erstellen, die tatsächlich testbar ist.

Definieren wir ein Paar Klassen für Ihre zwei Signale. (das AbstractFSM DSL erwartet eine Übereinstimmung in der Klasse):

%Vor%

Lassen Sie uns ein Paar enums für Ihre zwei Zustände definieren:

%Vor%

Definieren wir einen AbstractFSM Actor ( Ссылка ). Durch die Erweiterung von AbstractFSM können wir einen Akteur definieren, der eine Kette von FSM-Definitionen verwendet, die den obigen ähnlich sind, anstatt das Nachrichtenverhalten direkt in einer onReceive () -Methode zu definieren. Es bietet eine nette kleine DSL für diese Definitionen und (etwas bizarr) erwartet, dass die Definitionen in einem statischen Initialisierer eingerichtet werden.

Aber ein kurzer Umweg: AbstractFSM hat zwei Generics definiert, die zur Überprüfung der Kompilierzeit verwendet werden.

S ist die Basis von State-Typen, die wir verwenden möchten, und D ist die Basis von Datentypen. Wenn Sie eine FSM erstellen, die Daten speichert und ändert (möglicherweise ein Leistungsmesser für Ihren Lichtschalter?), Würden Sie eine separate Klasse für diese Daten erstellen, anstatt zu versuchen, Ihrer Unterklasse von AbstractFSM neue Mitglieder hinzuzufügen. Da wir keine Daten haben, definieren wir eine Dummy-Klasse, so dass Sie sehen können, wie sie weitergegeben wird:

%Vor%

Und damit können wir unsere Schauspielerklasse aufbauen.

%Vor%

Ich bin sicher, Sie fragen sich: Wie benutze ich das ?! Lassen Sie uns also ein Test-Harness mit JUnit und dem Akka Testkit für Java machen:

%Vor%

Und da sind Sie: ein FSM-Lichtschalter. Ehrlich gesagt, zeigt ein Beispiel dieses Trivial nicht wirklich die Stärke von FSMs, da ein datenfreies Beispiel als eine Menge von "werden / nicht-erhalten" Verhaltensweisen in ungefähr der Hälfte der LoC ohne Generika oder Lambdas durchgeführt werden kann. Viel besser lesbar IMO.

PS erwägen, Scala zu lernen, wenn man nur den Code anderer Leute lesen kann! Die erste Hälfte des Buches Atomic Scala ist kostenlos online verfügbar.

PPS Wenn alles, was Sie wirklich wollen, eine zusammensetzbare Zustandsmaschine ist, halte ich Pulleys , eine State-Machine-Engine, die auf Statecharts basiert in reinem Java. Es kommt in Jahren auf (viel XML und alte Muster, keine DI-Integration), aber wenn Sie wirklich die Implementierung einer Zustandsmaschine von den Inputs und Outputs entkoppeln wollen, kann dort Inspiration sein.

    
Matthew Mark Miller 25.06.2015, 04:29
quelle
2

Ich kenne Schauspieler in Scala.
Dieser Java Start Code kann Ihnen helfen, weiter zu gehen:

Ja, erweitere deine SimpleFSM von AbstractFSM .
Der Status ist ein enum in AbstractFSM .
Dein <someArguments> kann der Data Teil in deinem AbstractFSM
sein Ihre powerOn und powerOff sind Schauspieler Nachrichten / Ereignisse. Und die Zustandsumschaltung ist in den Übergängen Part

%Vor%

Wirklich arbeitendes Projekt siehe

Scala und Java 8 mit Lambda Template für einen Akka AbstractFSM

    
Robert Halter 20.06.2015 10:53
quelle

Tags und Links