Skip to content

sulmar/4developers-state-machine

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Maszyna stanu w praktyce

Kod źródłowy pochodzący z mojego wystąpienia na konferencji 4Developers

Wstęp

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.

Wymagania

  • .NET Core 3.1

Abstrakt

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.

State machine abstract

Przykład

State machine Lamp

Instalacja biblioteki

dotnet add package Stateless --version 5.1.3

Definicja maszyny stanów

Określamy typ stanu (State), typ wyzwalacza (Trigger) oraz stan początkowy (Init State).

StateMachine<LampState, LampTrigger> machine = new StateMachine<LampState, LampTrigger>(LampState.Off);

Konfiguracja przejść

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);

Uruchomienie wyzwalacza

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);

Pobranie bieżącego stanu

Console.WriteLine(machine.State)

Sprawdzenie wyzwalacza

machine.CanFire(LampTrigger.Push)

Śledzenie maszyny stanów

 machine.OnTransitioned(t=> Console.WriteLine($"{t.Source} -> {t.Destination}"));

Wygenerowanie grafu

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"]
}

Wizualizacja grafu

Diagram można wyświetlić na stronie:

Graph

Biblioteka Arduino

Automaton https://www.arduinolibraries.info/libraries/automaton

About

Przykłady z prezentacji "Maszyna stanów w praktyce" na konferencji 4Developers

Topics

Resources

Stars

1 star

Watchers

2 watching

Forks

Contributors

Languages