Manchmal möchte man in seinem Programm eine simple Zustandsmaschine nutzen, wobei man nicht auf bestehende Lösungen zurückgreifen möchte - weil sie zu unflexibel oder zu groß sind. Eine solche Zustandsmaschine kann dann auf verschiedenen Arten implementiert werden - häufig werden dabei verschachtelte Switch-Blöcke verwendet. Das vorliegende Beispiel zeigt eine andere, sinnvollere Implementierung auf Basis einer Schleife, die über Zustand-Übergangs-Klassen iteriert.
“State machine Beispiel” zeigt ein Beispiel einer solchen Zustandsmaschine, die Zustandsübergänge für ein Request-Objekt kontrollieren und anwenden soll:
Für unsere simple Zustandsmaschine implementieren wir - von Hilfsklassen abgesehen - nun drei Klassen:
- Die Zustandsmaschine
- Eine Klasse mit der Konfiguration
- Das eigentliche Request-Objekt
In der Klasse “StateMachine” steckt die ganze Logik: Hier wird schlicht über die hinterlegte Konfiguration iteriert. Wenn der gewünschte Zustandsübergang gefunden wurde, wird die entsprechende Status-Transition durchgeführt.
(Als Verbesserung könnte auch eine entspreche Fehlermeldung geworfen werden, sollte die gewünschte Transition nicht möglich sein.)
Die Konfiguration der Zustandsübergänge ist im “TransitionConfiguration” enthalten:
Das Code-Beispiel “Request” zeigt das Request-Objekt, das seinen aktuellen Status selbst vorhält:
Das vollständige Beispiel ist hier zu finden.
Die Vorteile dieser Implementierung sind vielfältig:
- Es wird keine separate Entität benötigt, um den aktuellen Objekt-Zustand zu speichern, der Zustand ist im Objekt (Request) selbst enthalten und kann mit diesem persistiert werden.
- Die Konfiguration der Status-Übergänge ist als Programmcode vorhanden. Damit können diese einfach in Unit Tests überprüft werden. Außerdem werden Fehler schon zur Compile-Zeit sichbar.
- Eine Erweiterung der Statemachine ist einfach möglich. Z.B. könnte die gewünschte Transition geprüft werden oder das Transition-Objekt könnte weitere Eigenschaft wie Vorbedigungen/Nachbedigungen enthalten, die die Statemachine ausführt.
- Die Zustandsmaschine muß kein Wissen über die möglichen Übergänge/Aktionen etc. besitzen.
- Damit sind keine ewig langen switch-Anweisungen für die Statusübergänge nötig.
- Die Zustandsmaschine kann sehr simpel gehalten werden
Ein anderes Beispiel für das Prinzip dieser Implementierung könnte eine Permission-Machine sein, die anstatt von Transitionen eine Liste von Permissions erhält. Dort wiederum könnte man Operation auf USer oder Domänen abbilden, die von der PermissionMachine überprüft werden.