Fiz alguns testes para aplicarmos máquina de estados no Laravel, e acho que seria legal compartilhar esse conhecimento para quem achar que pode ser útil :)
Wikipédia define melhor do que eu poderia resumir:
Uma máquina de estados finita (FSM - do inglês Finite State Machine) ou autômato finito é um modelo matemático usado para representar programas de computadores ou circuitos lógicos. O conceito é concebido como uma máquina abstrata que deve estar em um de um número finito de estados. A máquina está em apenas um estado por vez, este estado é chamado de estado atual. Um estado armazena informações sobre o passado, isto é, ele reflete as mudanças desde a entrada num estado, no início do sistema, até o momento presente. Uma transição indica uma mudança de estado e é descrita por uma condição que precisa ser realizada para que a transição ocorra. Uma ação é a descrição de uma atividade que deve ser realizada num determinado momento.
Para testes defini uma máquina de estados representado 4 diferentes estágios do desenvolvedor:
- Acordando
- Comendo
- Fritando
- Dormindo
Só esses 4 estados são possíveis, e para trocar entre eles é preciso definir os 'caminhos'. Defini as seguintes transições para trocar entre os estados:
- Comer (vai pro estado Comendo)
- Tomar café (vai pro estado Fritando)
- Dormir (vai pro estado Dormindo)
- Acordar (vai pro estado Acordando)
Como uma imagem vale mais que mil palavras, taí um gif pra explicar as transições:
Para aplicar o conceito de máquina de estados no PHP um pacote bastante recomendado foi o do winzou, e para minha sorte, já existe um service provider pro laravel disponível no Github.
Instalei o plugin no laravel, defini a máquina de estados e fiz os seguintes testes:
// Pegando um usuario do banco
$u = App\Usuario::find(1);
// Definindo um estado inicial
$u->estado = 'dormindo';
// Iniciando a maquina de estados para o usuario
$fsm = StateMachine::get($u, 'fsm');
// Perguntando o estado atual
$fsm->getState();
=> "dormindo"
// Verificar quais os possíveis estado futuros
$fsm->getPossibleTransitions();
=> [
1 => "levantar",
]
// Aplicando uma transição
$fsm->apply("levantar");
=> true
$fsm->getState();
=> "acordando"
$fsm->getPossibleTransitions();
=> [
0 => "comer",
2 => "tomar_cafe",
]
// Vendo se pode aplicar a transição dormir
$fsm->apply("dormir");
=> false
// Não pode, acabou de acordar!
// Vendo se pode aplicar a transição comer
$fsm->apply("comer");
=> true
// Pode comer sim
// Bateu a larica?
$fsm->apply("comer");
=> true
$fsm->getState();
=> "comendo"
$fsm->getPossibleTransitions();
=> [
2 => "tomar_cafe",
3 => "dormir",
]
// Tomar um cafézinho pra dar uma acordada
$fsm->apply("tomar_cafe");
=> true
$fsm->getState();
=> "fritando"
$fsm->getPossibleTransitions();
=> [
0 => "comer",
2 => "tomar_cafe",
3 => "dormir",
]
Para salvar o estado do usuário é necessário dar um $u->save()
.
A máquina de estados também pode chamar métodos dos controllers, antes e depois de aplicar uma transição, dando total controle ao trocar estados e aplicar regras de negócios específicos.
Bom dia, você poderia me fornecer o projeto laravel, que você implementou esse projeto demonstrado?