<dependency> <groupId>com.github.stateless4j</groupId> <artifactId>stateless4j</artifactId> <version>2.6.0</version> </dependency>
Introducción
Cree máquinas de estado y flujos de trabajo ligeros basados en máquinas de estado directamente en código java.
StateMachineConfig<State, Trigger> phoneCallConfig = new StateMachineConfig<>();phoneCallConfig.configure(State.OffHook) .permit(Trigger.CallDialed, State.Ringing);phoneCallConfig.configure(State.Ringing) .permit(Trigger.HungUp, State.OffHook) .permit(Trigger.CallConnected, State.Connected);// this example uses Java 8 method references// a Java 7 example is provided in /examplesphoneCallConfig.configure(State.Connected) .onEntry(this::startCallTimer) .onExit(this::stopCallTimer) .permit(Trigger.LeftMessage, State.OffHook) .permit(Trigger.HungUp, State.OffHook) .permit(Trigger.PlacedOnHold, State.OnHold);// ...StateMachine<State, Trigger> phoneCall = new StateMachine<>(State.OffHook, phoneCallConfig);phoneCall.fire(Trigger.CallDialed);assertEquals(State.Ringing, phoneCall.getState());
stateless4j es un puerto sin estado para java
Características
La mayoría de las construcciones de máquinas de estado estándar son compatibles:
- Soporte genérico para estados y disparadores de cualquier tipo java (números, cadenas, enumeraciones, etc.).)
- Estados jerárquicos
- Eventos de entrada / salida para estados
- Cláusulas de guardia para admitir transiciones condicionales
- Las acciones definidas por el usuario se pueden ejecutar al hacer la transición
- Transiciones internas (sin llamar
onExit
/onEntry
) - Introspección
También se proporcionan algunas extensiones útiles:
- Disparadores parametrizados
- Estados de reentrada
Estados jerárquicos
En el ejemplo siguiente, el estado OnHold
es una subestación del estado Connected
. Esto significa que una llamada OnHold
sigue conectada.
phoneCall.configure(State.OnHold) .substateOf(State.Connected) .permit(Trigger.TakenOffHold, State.Connected) .permit(Trigger.HungUp, State.OffHook) .permit(Trigger.PhoneHurledAgainstWall, State.PhoneDestroyed);
Además de la propiedad StateMachine.getState()
, que reportará el estado actual preciso, se proporciona un método isInState(State)
. isInState(State)
tendrá en cuenta las subestaciones, de modo que si el ejemplo anterior estaba en el estadoOnHold
, isInState(State.Connected)
también evaluaría a true
.
Eventos de entrada/salida
En el ejemplo, el método startCallTimer()
se ejecutará cuando se conecte una llamada. El stopCallTimer()
se ejecutará cuando se complete la llamada (colgando o lanzando el teléfono contra la pared).)
La llamada puede moverse entre los estados Connected
y OnHold
sin que los métodos startCallTimer(
) y stopCallTimer()
se llamen repetidamente porque el estado OnHold
es una subestación del estado Connected
.Los controladores de eventos de entrada/salida
se pueden suministrar con un parámetro de tipo Transition
que describe los estados de desencadenador,origen y destino.
Acción en transición
Es posible ejecutar una acción definida por el usuario al hacer una transición.Para una transición’ normal ‘o’ reentrante’, se llamará a esta acción sin ningún parámetro. Para transiciones’ dinámicas ‘ (aquellos que calculan el estado de objetivo basado en parámetros dados por el disparador), los parámetros del disparador se darán a la acción.
Esta acción solo se ejecuta si la transición se realiza realmente; por lo tanto, si la transición está protegida y la guardia prohíbe una transición, entonces la acción no se ejecuta.
Si se realiza la transición, la acción se ejecutará entre el controladoronExit
del estado actual y el controlador onEntry
del estado de destino (que podría ser el mismo estado en caso de reentrada.
Licencia
Apache 2.0 Licencia
Creada por @oxo42
Mantenida por Chris Narkiewicz @ezaquarii