Java Enum-based State Machine (FSM): Ereignisse übergeben

Ich verwende mehrere enum-basierte Zustandsautomaten in meiner Android-Anwendung. Während diese sehr gut funktionieren, suche ich nach einem Vorschlag, wie Ereignisse, normalerweise von registrierten Rückrufen oder von Eventbus-Nachrichten, elegant in den derzeit aktiven Zustand versetzt werden können. Von den vielen Blogs und Tutorials zu auf Aufzählungen basierenden FSMs geben die meisten Beispiele für Zustandsautomaten, die Daten (z. B. Parser) verwenden, anstatt zu zeigen, wie diese FSMs von Ereignissen gesteuert werden könne

Eine typische Zustandsmaschine, die ich verwende, hat folgende Form:

private State mState;

public enum State {

    SOME_STATE {


        init() {
         ... 
        }


        process() {
         ... 
        }


    },


    ANOTHER_STATE {

        init() {
         ... 
        }

        process() {
         ... 
        }

    }

}

...

n meiner Situation lösen einige der Zustände eine Arbeit aus, die an einem bestimmten Objekt ausgeführt werden soll, und registrieren einen Listener. Das Objekt ruft asynchron zurück, wenn die Arbeit erledigt ist. Mit anderen Worten, nur eine einfache Callback-Schnittstelle.

Ebenso habe ich einen EventBus. Klassen, die erneut über Ereignisse informiert werden möchten, implementieren eine Callback-Schnittstelle undlisten() für diese Ereignistypen auf dem EventBus.

Das Grundproblem besteht daher darin, dass die Zustandsmaschine oder ihre einzelnen Zustände oder die Klasse, die die Aufzählung FSM enthält, oderetwa muss diese Callback-Schnittstellen implementieren, damit sie Ereignisse mit dem aktuellen Status darstellen können.

in Ansatz, den ich verwendet habe, gilt für das gesamteenum, um die Callback-Schnittstelle (n) zu implementieren. Die Aufzählung selbst verfügt über Standardimplementierungen der Rückrufmethoden im unteren Bereich, und die einzelnen Zustände können diese Rückrufmethoden für Ereignisse, an denen sie interessiert sind, überschreiben Es besteht das Risiko, dass der Rückruf in einem Zustand ausgeführt wird, der nicht der aktuelle ist. Ich werde mich wahrscheinlich daran halten, wenn ich nichts Besseres finde.

Ein anderer Weg ist, dass die enthaltende Klasse die Rückrufe implementiert. Anschließend muss es diese Ereignisse an die Zustandsmaschine delegieren, indem es @ aufrufmState.process( event ). Das bedeutet, dass ich Ereignistypen aufzählen muss. Beispielsweise

enum Events {
    SOMETHING_HAPPENED,
    ...
}

...

onSometingHappened() {

    mState.process( SOMETHING_HAPPENED );
}

Ich mag das jedoch nicht, weil (a) ich die Hässlichkeit hätte,switch zu den Ereignistypen innerhalb desprocess(event) von jedem Zustand und (b) Durchlaufen von zusätzlichen Parametern sieht umständlich aus.

Ich hätte gerne einen Vorschlag für eine elegante Lösung, ohne auf eine Bibliothek zurückgreifen zu müssen.

Antworten auf die Frage(7)

Ihre Antwort auf die Frage