Kod źródłowy pochodzący z mojego wystąpienia na konferencji 4Developers
Maszyna stanów może wydawać się nudną, matematyczną koncepcją, o której zwykle zapominamy wraz z zaliczonym egzaminem na studiach. Okazuje się jednak, że dzięki niej można uprościć wiele problemów spotykanych w biznesowych projektach. Pokażę Wam jak użyć maszyny stanów w aplikacji .NET Core i udoskonalić nasze projekty.
- .NET Core 3.1
Maszyna stanów to zbiór stanów states (s1, s2 ... sN) oraz przejść triggers (t1, t2 ... tN). Obiekt może znajdować się w jednym momencie tylko w jednym ze stanów. Na początku maszyna stanów przyjmuje stan początkowy. Przejścia pomiędzy stanami następują za pomocą triggerów.
dotnet add package Stateless --version 5.1.3Określamy typ stanu (State), typ wyzwalacza (Trigger) oraz stan początkowy (Init State).
StateMachine<LampState, LampTrigger> machine = new StateMachine<LampState, LampTrigger>(LampState.Off);Za pomocą metody Configure() oraz Permit() definiujemy dopuszczalne przejścia. Dodatkowo za pomocą metod OnEntry() i OnExit() możemy zdefiniować dodatkowe akcje, które mają być uruchamianie przy wejściu lub po wyjściu ze stanu.
machine = new StateMachine<LampState, LampTrigger>(LampState.Off);
machine.Configure(LampState.Off)
.Permit(LampTrigger.Push, LampState.On);
machine.Configure(LampState.On)
.Permit(LampTrigger.Push, LampState.Blinking)
.OnEntry(() => Console.WriteLine("Send sms"), "Send sms");
machine.Configure(LampState.Blinking)
.Permit(LampTrigger.Push, LampState.Off);Na podstawie wcześniej zdefiniowanej konfiguracji nastąpi przejście do kolejnego stanu. Jeśli przejście nie zostało zdefiniowane pojawi się Exception.
machine.Fire(LampTrigger.Push);Console.WriteLine(machine.State)machine.CanFire(LampTrigger.Push) machine.OnTransitioned(t=> Console.WriteLine($"{t.Source} -> {t.Destination}"));Console.WriteLine(Stateless.Graph.UmlDotGraph.Format(machine.GetInfo()));Zostanie wygenerowany graf w formacie DOT Graph,
digraph {
compound=true;
node [shape=Mrecord]
rankdir="LR"
Off [label="Off"];
On [label="On|entry / Send sms"];
Blinking [label="Blinking"];
Off -> On [style="solid", label="Push"];
On -> Blinking [style="solid", label="Push"];
Blinking -> Off [style="solid", label="Push"];
init [label="", shape=point];
init -> Off[style = "solid"]
}
Diagram można wyświetlić na stronie:
Automaton https://www.arduinolibraries.info/libraries/automaton


