Estado-machine: Como mudar de estado sem evento externo (estado transiente)?

StackOverflow https://stackoverflow.com/questions/884081

  •  22-08-2019
  •  | 
  •  

Pergunta

O cenário:
Eu tenho uma máquina de estado simples:

caminho feliz:

Uninitialized->Initialized->InProgress->Done

caminho infeliz:

Uninitialized->Initialized->Error

Basta colocar, eu preciso fazer uma transição (seja em InProgress ou em estado de erro) sem um evento externo / gatilho . Ou seja, estado inicializado deve resultar imediatamente em um desses estados.

Perguntas:

  1. É OK para transição de estado causa de dentro Initialized.Enter () ?
  2. Eu poderia usar guardas Estado para fazer isso, mas eu prefiro não ter lógica não-trivial na guarda do Estado (e inicialização pode muito bem ser complexo).
  3. Se não é OK, como posso fazê-lo de forma diferente?
  4. Devo apenas tomar esta decisão fora de ele FSM todos juntos e ter algum outro componente causa a transição apropriada? Mas então, não seria eu ainda tenho que chamar esse componente externo a partir do Initialized.Enter () ? por isso não resolve nada?
Foi útil?

Solução

Em uma máquina de estado, próximo estado é uma função lógica combinatória de entrada e estado atual.

No caso você está descrevendo, a mesma causa (estado Initialized) parece ser capaz de desencadear dois efeitos diferentes (quer InProgress ou estaduais Error). Eu acho que há uma entrada oculta cujo valor faz a diferença. Eu também acho que essa entrada é recebido durante a transição de Uninitialized para Initialized.

Portanto, eu teria um modelo diferente:

Uninitialized -> Successfully initialized -> InProgress -> Done
             \
              `-> Failed Initialization -> Error

combinando Possivelmente Successfully initialized com InProgress e Failed initialization com Error.


Editar : Desde o seu comentário, eu entendo que a entrada escondida na verdade é o resultado de uma ação (a inicialização do dispositivo). Tomar o seu modelo, presumo que a inicialização ocorre enquanto no estado Initialized (vamos chamá-lo Initializing). Desta forma, o resultado do dispositivo é o seu evento externo que irá desencadear transição quer para InProgress ou para Error.

Portanto, manter a sua máquina de estado e simplesmente adicionar o resultado de device.Initialize() à lista de entradas ou de eventos externos.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top