Visual Studio 2010!

Read now >

View Now
DevSource RSS FEEDS
XML Want an easy way to keep up with breaking tech news? And the Get DevSource headlines delivered to your desktop with RSS.
ADVERTISEMENT
ADVERTISEMENT

 

DevSource.com: Your Source for Visual Studio on Facebook
ADVERTISEMENT
Object-Oriented State Machines
By Jon Shemitz

Rate This Article: Add This Article To:

Object-Oriented State Machines
( Page 1 of 3 )

Maybe you haven't worked with state machines since your college computer science courses. Jon Shemitz offers a reason to dust off the technique with .NET: object-oriented state machines can be easier to read and debug than their enum and

State machines are old technology, but they have many uses even for modern programmers. Probably the most common reason to build a state machine on .NET is emulating coroutines in recursive IEnumerator, such as one that must return a FileSystemInfo for every file and directory under a starting directory. Since this only takes three states, that's exactly what the sample code for this article (StateMachines.zip) can do. In Whidbey, iterators will eliminate the need to emulate coroutines, but Whidbey may still be as much as a year out—and even when Whidbey arrives, there will still be uses for state machines in .NET programming.

The basic idea is that you execute a state machine iteratively, when you need to extract the next value from an input stream, or when a new input comes in. The Current state controls which code is executed on each iteration; the Current state's handler may or may not change the Current state. If the Current state handler doesn't change the Current state, the same handler is invoked each time the state machine is iterated, until something changes.

The canonical way to implement a state machine is via an enum containing the name of every state, and a giant switch statement containing the handler for each enum. This compiles to a nice efficient jump table, but it's hard to maintain. When you add a new state, you have to change both the enum and the switch statement; plus, tracing execution means lots of jumping around the switch statement.

After writing an IEnumerator as an enum and switch state machine, I got to wondering: if an object is just a state packet, could you swap state by changing the CurrentState object, instead of the CurrentEnum value? Each state's handler would stand by itself as a standard method, which is easier to read than a long switch statement. Adding a new state just means adding a new class, which is easier than editing both the enum and the switch. And when a handler changes the CurrentState, you can use F12 to jump to the implementation of the next state, which is easier than having to find it by hand in a long switch statement.

The interface between IEnumerator and a state machine is pretty obvious: Reset() sets CurrentState to an initial state. MoveNext() iterates the state machine, either setting an internal CurrentValue field and returning true, or returning false to indicate that there are no (more) items. And the Current property exposes the internal CurrentValue field.

Each state handler needs to be able to change the enumerator's private CurrentState field. That is, we need a circular reference where the state machine refers to the current state object, and the state handler has a reference back to the state machine.



 
 
>>> More ASP and .Net Coding Techniques Articles          >>> More By Jon Shemitz