StateMachine, les automates séquentiels

Il est possible via le design pattern Etats de gérer une application tournant autour de changements d’état. Mais dans le cas de gestion d’état au sein d’une machine, il est préférable d’utiliser un template : La StateMachine.

La StateMachine est un template d’application. Elle propose une solution, basée principalement sur une classe et deux enumérateurs, pour faire succéder des états. Ici, les états ont donc davantage le sens d’Etapes ; on peut sinon parler de processus qui se succède, suite à des transitions.

StateTransition

Une des mécaniques de base est permit grâce au concept de StateTransition.

public class StateTransition
{
   public EState State { get; set; }
   public EInput Input { get; set; }

   public StateTransition(EState eState, EInput eInput)
   {
      State = eState;
      Input = eInput;
   }
}
public enum EState {Active, Inactive}
public enum EInput {PowerOn,PowerOff}

Une StateTransition va définir, pour un état donné, une commande possible.

Transitions

Cela va permettre par la suite, de définir un Dictionnary<StateTransition,EState> définissant, pour une StateTransition donné (machine en Etat A, pour une opération 1), un Etat qui lui succédera.

Implémentation

Il faut maintenant considérer une classe StateMachine qui aura un état courant, et un ensemble de transitions.

//class StateMachine

Dictionary<StateTransition, EState> Transitions { get; set; }
public EState CurrentState { get; set; }

public StateMachine()
{
   CurrentState = EState.Inactive;

   Transitions = new Dictionary<StateTransition, EState>()
   {
      {new StateTransition(EState.Inactive,EInput.PowerON), EState.Active },
      {new StateTransition(EState.Inactive,EInput.PowerOFF), EState.Inactive},
      {new StateTransition(EState.Active,EInput.PowerON), EState.Active},
      {new StateTransition(EState.Active,EInput.PowerOFF), EState.Inactive },
   }; 
}

Les transitions ici définies vont permettre la transition d’un état à un autre.

Ensuite, les méthodes de la StateMachine procèderont à une opération définie et pourront faire évoluer son état :

public EState DoSomething(EInput eInput)
{
   //Instructions...

   CurrentState = GetNext(eInput);
   return CurrentState;
}

private EState GetNext(EInput eInput)
{
   EState ret;
   StateTransition thisTransition = new StateTransition(CurrentState, eInput);
   Transitions.TryGetValue(thisTransition, out ret);

   return ret;
}

Ainsi, ce template permet de connaître un état interne d’un automatisme sensé appliquer un processus isolé. Une de ces forces est la lisibilité permise pour ces changements d’état.

StateMachine myStateMachine = new StateMachine();
Console.WriteLine("CurrentState : " + myStateMachine.CurrentState);
Console.WriteLine("User inputs PowerON ; Effect : " + myStateMachine.DoSomething(EInput.PowerON));

Evolutions

Il est aussi possible d’envisager un fonctionnement autonome.

A la place, la StateMachine peut être codée pour implémenter un enchainement dynamique de ses Etats (ou Etapes) à la fin d’une opération validée.

Imaginons une StateMachine dont les opérations sont, à la manière d’une caisse automatique de super marché, d’actionner un tapis roulant pour recevoir des pièces, de compter les pièces puis de rendre la monnaie.

public StepAction Initialize(EInput eInput)
{
   StartTravolator();
   return new StepAction(WaitForMoney);
}

public StepAction WaitForMoney()
{
   while(NoMoney)
      Threads.Sleep(500);

   return new StepAction(CountMoney);
}

public StepAction CountMoney()
{
   while(CoinNotIdentified)
      Value += IdentifieValue(Coin);

   return new StepAction(ReturnChange)
}

public StepAction ReturnChange(EInput eInput)
{
   if(Value >WaitedValue)
      ReturnChangeToCustomer(Value-WaitedValue);

   return new StepAction(null);
}

De cette manière, l’automate dispose de toutes les méthodes nécessaire à la réalisation de sa tâche, dont le processus dépend directement d’état/étapes facilement identifiables.

 

Sources
  • http://www.ni.com/tutorial/3024/en/
  • https://stackoverflow.com/questions/5923767/simple-state-machine-example-in-c
  • Expérience professionnel
  • https://medium.com/datadriveninvestor/state-machine-design-pattern-why-how-example-through-spring-state-machine-part-1-f13872d68c2d

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *