A simpler DSL for GUI state machines

written by tobinharris on June 30th, 2008 @ 06:12 AM

I can't seem to get State Machines off my brain this week, sad isn't it?

I find that I use them so rarely, yet I have a nagging feeling they could be so incredibly useful. I think it's ultimately because they could let me separate concerns.

Take today for example, I was building run-of-the-mill ASP.NET wizard/form with roughly the following steps. This GUI workflow is to implement a simple online survey that people can submit.

State Machine

I started out without even thinking about state machines. I just had the use-case docs on my desk, and was hacking some ASP.NET page together. It was getting messy fast.

I really wanted to use some implementation of the state pattern. But, one gripe is that implementations of the state pattern tend to take so much plumbing code to express the state transitions. This article demonstrates my point, I just didn't have time to invest in that much "stuff" (not wanting to diss the author, much of it looks fantastic, I just wanted something easier). Even drawing a state diagram takes too much time IMHO.

I was trying to dream up a simpler way of expressing this state machine kind of thing in code, and so far have come up with the following. Note that so far I'm only communicating states and transitions, but it's a start:

Start -> [Introduction || AlreadyDone]        
Introduction -> Terms -> Scores <-> Nomination <-> Confirm -> Thanks 
[Terms, Scores, Nomination] -> Saved for Later

If I could make this into C# I could then express the 15 possible transitions in only 3 lines of code!! I like that a LOT. In case you're wondering what the symbols mean, here's a brief explanation:

  • -> for a one way transition
  • <-> for a two way transition (essentially 2 separate transitions)
  • Grouping similar transitions using [a, b, c]->d

I've just got started thinking and playing with this stuff, and I hope I can take it somewhere useful!



kick it on DotNetKicks.com



Comments

  • jbland on 01 Jul 00:06

    have you looked at this

    http://www.codeplex.com/SimpleStateMachine

  • Tobin Harris on 01 Jul 01:10

    Interesting. I must say the DSL looks very simple yet expressive.

    The ideal I’m aiming for is a SM framework that needs a tiny amount of plumbing.

    I looked through the demo app on codeplex and it seems to be quite involved (builders for creating state machines from definitions, binding and unbinding of workflows, binding and unbinding of state machines, event handlers, DSL factories etc). I guess it’s 100x simpler and more testable than WWF though!

    I bet it’s not too bad once you get around that, but I was hoping for something a little more “works straight out of the box”. Something that only 1 or 2 concepts that I need to teach my small brain in order to get started :)

  • Ray on 01 Jul 01:29

    Why make a mountain out of a mole hill. State machines can be as simple as a switch statement implementation:

    enum enumStates { state1, state2, state3 } State; State = state1; switch (State) { case state1: // do something State = state2; break; case state2: // do something State = state3; break; case state3: // do something State = state1; // and start all over again break; }

  • Casper Bang on 01 Jul 02:33

    I would do it with enums, with enums in Java you can easily model the transitions using self-relations. I assume you can do the same for C#:

    enum State{ DONE, THANKS, ... }

    private EnumSet<state> transitionableStates;
    public State(State... states){
        transitionableStates= EnumSet.copyOf( Arrays.asList(states));
    }
  • steve j on 01 Jul 04:37

    “If I could make this into C# I could then express the 15 possible transitions in only 3 lines of code”

    You should look at Workflow Foundation. It’s poorly named, but it does what you’re after.

    Read chapter one of the “Essentials” book. Read it twice.

  • steve j on 01 Jul 05:23

    If you don’t already have the book ;), you can get an idea from the reviews on amazon: http://www.amazon.com/Essential-Workflow-Foundation-Microsoft-Development/dp/0321399838

  • Pradeep on 01 Jul 11:58

    Here, what I had done for expressing state machine in one of my past project. The idea is acquired from the mathematical modal called Deterministic Finite Automation on which Most of the commonly used compiles (Lexical Analyzer) are designed. (http://www.cs.iitm.ernet.in/tell/automata/Automata/fsa.htm)

    This is the definition; A state machine consist of - a set of states S - a set of transition T - a state s0 that is distinguished as the initial state - a set of states F distinguish as final states - and for each transition t1, t2 leaving state s as t1 ≠ t2 can be easily represented as a 2-dimentional matrix (2-dimentional array) in which one axis represents all possible state and the other for all possible transition, and returning resulting next state. Here is a sample state machine represented in a 2-dimentional array. int[][] stateTransitionMatrix = new int3;

    stateTransitionMatrixSTATUS_INIT = STATUS_NEW; stateTransitionMatrixSTATUS_NEW = STATUS_ACTIVE; . . . stateTransitionMatrixSTATUS_ACTIVE = STATUS_CLOSE; I found this is more simple way of expressing state machine for any business model and would lead to a centralized state management mechanism.

  • Pradeep on 01 Jul 12:13

    found my sample code is not clear enough, here its again;

    int[][] stateMachine = new int3; . . stateMachine STATUS_INIT = STATUS_NEW; stateMachine STATUS_NEW = STATUS_ACTIVE; . . stateMachine STATUS_ACTIVE = STATUS_CLOSE;

  • Pradeep on 01 Jul 12:20

    hope it would work now stateMachine STATUS_NEW = STATUS_ACTIVE;
    .
    .
    .
    stateMachine STATUS_ACTIVE = STATUS_CLOSE;

    int[][] stateMachine = new int3[3];

    stateMachine STATUS_INIT = STATUS_NEW;

  • Pradeep on 01 Jul 13:52

    check it here;

    http://neerosh.blogspot.com/2008/07/state-management-in-business-entities.html

  • Chris Barham on 01 Jul 14:36

    You could use imatix Libero to draw the state machine and then generate code – http://legacy.imatix.com/html/libero/ (although c# isn’t generated similar languages are – e.g. Java – and it’s pretty simple to add extra languages)

  • Tobin Harris on 01 Jul 15:25

    @Ray Switch statements are a classic approach to FSMs as far as I know. However, don’t you find they get difficult to follow and manage?

    I’d be happy using switch statements if my FSM were generated from a diagram or other DSL.

    I think I want a terse, simple FSM representation that can live in my code (Business Entities or GUIS) and be simple, clear and expressive.

    @Casper That looks promising, can you explain how it would work for several states, each with it’s own set of permissable transitions? Also, can you get events into the mix?

    @Steve J Will get to Borders and see if I can read that first chapter a few times, thanks for the tip :)

    @Pradeep That kind of simplicity is definately along the right lines for what I was thinking. I like that you’ve got events into the picture whilst leaving it clean.

    @Chris Looks interesting, will check it out more closely as the guys who built that (last decade!) seem to know their stuff. It seems to use a generator on top of the DSL, and personally I’d rather not use generators. Also, adding extra tooling into the mix feels wrong too.

  • bill kress on 12 Jul 05:53

    I wrote one in Java a little while ago. It uses a finite-state table to express the entire state machine. It’s completely event driven, allows OO development. Each activity is an object instead of a entry in a switch statement, so the objects can be extended and included in a hierarchy or they can be implemented as inner classes allowing them to share data.

    The state transition table is defined as simply as it can possibly be, just a simple array definition in a 2d format (table).

    I uploaded the whole thing (including examples) here:

    http://code.google.com/p/state-machine/

Post a comment

Options:

Size

Colors