Finite State Machine 4 java
He liberado una librería que implementa máquinas de estado finitas para Java. Quién no se ha encontrado en un sistema altamente concurrente con el problema de manejar el estado de una clase que debe reaccionar a un montón de eventos manejando secciones críticas y demás? Normalmente, si uno no ofrece un patrón para estos problemas, resolver un estado complejo en un sistema concurrente necesita de locks + un montón de ifs + un montón de código repetitivo... y eso resulta en un sistema con bastantes posibles problemas.
Después de haber implementado soluciones similares múltiples veces, he decidido liberarlo bajo open source. Podéis encontrar más información (en inglés) aquí y la librería aquí.
Es una librería modesta (he intentado mantenerla tan sencilla como he podido) y que añade algunas anotaciones para facilitar la declaración de máquinas de estado. Por ejemplo, un código coomo:
@AStateMachine public class LegalStateMachineTest { @State(isStart=true) public static final String STATE_A = "STATE_A"; @State public static final String STATE_B = "STATE_B"; @State public static final String STATE_COND = "STATE_COND"; @State public static final String STATE_D = "STATE_D"; @Event public static final String EVENT_AB = "EVENT_AB"; @Event public static final String EVENT_BB = "EVENT_BB"; @Event public static final String EVENT_BC = "EVENT_BC"; @Event public static final String EVENT_CD = "EVENT_CD"; @Transitions({@Transition(source=STATE_A, target=STATE_B, event=EVENT_AB), @Transition(source=STATE_B, target=STATE_COND, event=EVENT_BC), @Transition(source=STATE_COND, target=STATE_D, event=EVENT_CD)}) public void noop(TransitionInfo info) { System.out.println("#tx: " + info); } @ExitState(STATE_A) public Boolean exitA(TransitionInfo info) { System.out.println("#exit: " + info); return true; } @EnterState(STATE_COND) public EventInfo transitionBC(TransitionInfo info) { System.out.println("#enter: " + info); return new EventInfo(EVENT_CD, null); } @Test public void test() throws StateMachineException { StateMachine sm = StateMachines.newNonReentrant(this); sm.processEvent(EVENT_AB, null); sm.processEvent(EVENT_BC, null); Assert.assertEquals(sm.getCurrentState(), STATE_D); } }
generaría un output como:
#exit: [STATE_A + EVENT_AB -> STATE_B] #tx: [STATE_A + EVENT_AB -> STATE_B] #tx: [STATE_B + EVENT_BC -> STATE_COND] #enter: [STATE_B + EVENT_BC -> STATE_COND] #tx: [STATE_COND + EVENT_CD -> STATE_D]
Cualquier feedback es más que bienvenido. Si a alguien le sirve para resolver un problema más fácilmente, ya estaré más que contento.
Nota: noticia enviada por xavi.ferro
Reader Comments (2)
Buena iniciativa! Realmente yo nunca me he encontrado en esa situación, pero me lo apunto por si acaso.
Por cierto, yo también estoy escribiendo desde Suiza! ^_ ^
Gracias por tu post.
Así que en Suiza también? Pues sí que es pequeño el mundo :-D
En cuanto al patrón, lo utilicé principalmente para software en telecomunicaciones (protocolos tipo SIP o RTP) y gateways de voz, donde la especificación del protocol define las máquinas de estado y el problema, bajo tanta carga, se complica considerablemente.
Saludos