Finite State Machine 4 java
jueves, septiembre 5, 2013 at 11:42AM
javaHispano

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

Article originally appeared on javaHispano (http://www.javahispano.org/).
See website for complete article licensing information.