<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>8th Light Blog: Understanding Statemachines, Part 1: States and Transitions</title>
    <link>http://blog.8thlight.com/articles/2006/11/17/understanding-statemachines-part-1-states-and-transitions</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>In the minds of the craftsmen...</description>
    <item>
      <title>Understanding Statemachines, Part 1: States and Transitions</title>
      <description>&lt;h3&gt;Introduction:&lt;/h3&gt;

&lt;p&gt;I consider State Machines to be a programming gem.  An invaluable tool for the software craftsman&amp;#8217;s toolkit.  It&amp;#8217;s not everyday that a statemachine comes in handly, but for some problems statemachines are the most elegant and robust solution you&amp;#8217;ll find.&lt;/p&gt;

&lt;p&gt;Perhaps you learned about Finite State Automata in school but could use a refresher.  Or perhaps you&amp;#8217;ve never heard of these crazy statemachines in your entire software career and your curiosity is piqued.  This is a place to learn more.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve found statemachines so valuable I&amp;#8217;ve build a &lt;a href="http://rubyforge.org/projects/statemachine/"&gt;Ruby framework to build statemachines&lt;/a&gt;.  I hope you find this tool valuable&amp;#8230; but for that to happen you have to understand statemachines.  To that end, this is the first installment of a complete statemachine lesson.  Statemachines are simple.  You&amp;#8217;ll see.&lt;/p&gt;

&lt;h3&gt;States and Transitions:&lt;/h3&gt;

&lt;div style="text-align: center;"&gt;&lt;img style="border: 1px solid black" src="/files/vending_machine.png"&gt;&lt;br/&gt;&lt;b&gt;The Vending Machine Statemachine Diagram&lt;/b&gt;&lt;/div&gt;

&lt;p&gt;Above is a UML diagram of the statemachine the runs a simple vending machine.  We can see that there are two rectangles with rounded corners.  These are &lt;strong&gt;States&lt;/strong&gt;.  The vending machine has two possible states, &lt;em&gt;Waiting&lt;/em&gt; and &lt;em&gt;Paid&lt;/em&gt;.  At any given time during execution, the vending machine will be in one of these states.&lt;/p&gt;

&lt;p&gt;Note the arrows going from one state to another.  These are called &lt;strong&gt;Transitions&lt;/strong&gt;. Transitions are how statemachines change state.  Also note that each transition is labeled with an &lt;strong&gt;Event&lt;/strong&gt;.  Events are the input to statemachines. They invoke transitions.  For example, when the vending machine is in the &lt;em&gt;Waiting&lt;/em&gt;  state and the &lt;em&gt;dollar&lt;/em&gt; event is received, the statemachine will transition into the &lt;em&gt;Paid&lt;/em&gt; state.  When in the paid state and the &lt;em&gt;selection&lt;/em&gt; event is received, the statemachine will transition back into the &lt;em&gt;Waiting&lt;/em&gt; state.&lt;/p&gt;

&lt;p&gt;This should seem reasonable.  Imagine a real vending machine.  When you walk up to it it&amp;#8217;s waiting for you to put money in.  You pay by sticking a dollar in and then you make your selection.  After this happy transaction, the vending machine waits for the next client.&lt;/p&gt;

&lt;p&gt;This scenario is not the only possibility though.  Statemachine are very helpful in examining all possible flows through the system.  Take the &lt;em&gt;Waiting&lt;/em&gt; state.  We don&amp;#8217;t normally expect users to make selections if they haven&amp;#8217;t paid but it&amp;#8217;s a possibility.  As you can see this unexpected event is handled by our vending machine.  It will simply continue to wait for your dollar.  And it would be foolish for someone to put more money in the the vending machine if they&amp;#8217;ve already paid. Foolish or not, you and I know it happens.  Our vending machine handles this graciously by taking the money and allowing the user to make a selection for the fist dollar they supplied.  Effectively the client loses the extra money they put in. &lt;em&gt;(grin)&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;Implementing the Statemachine:&lt;/h3&gt;

&lt;p&gt;We have identified 3 fundamental components to a statemachine: &lt;strong&gt;States, Transitions, and Events&lt;/strong&gt;.  It turns out that the simplest way to define a statemachine is to define its transitions.  Each transition can be defined by identifying the state where it begins, the event by which is invoked, and the state where it ends.  Using this scheme we can define out vending machine like so&amp;#8230;&lt;/p&gt;

&lt;table style="border: 1px solid black; margin: 10px;"&gt;
&lt;tr&gt;&lt;th&gt;Origin State&lt;/th&gt;&lt;th&gt;Event&lt;/th&gt;&lt;th&gt;Destination State&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Waiting&lt;/td&gt;&lt;td&gt;dollar&lt;/td&gt;&lt;td&gt;Paid&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Paid&lt;/td&gt;&lt;td&gt;selection&lt;/td&gt;&lt;td&gt;Waiting&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Waiting&lt;/td&gt;&lt;td&gt;selection&lt;/td&gt;&lt;td&gt;Waiting&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Paid&lt;/td&gt;&lt;td&gt;dollar&lt;/td&gt;&lt;td&gt;Paid&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;Defining it in ruby is not much harder:&lt;/p&gt;

&lt;pre&gt;require 'rubygems'
require 'statemachine'

vending_machine = Statemachine.build do
  trans :waiting, :dollar, :paid
  trans :paid, :selection, :waiting
  trans :waiting, :selection, :waiting
  trans :paid, :dollar, :paid
end&lt;/pre&gt;

&lt;p&gt;The above snippet assumes you have the &lt;em&gt;statemachine&lt;/em&gt; gem installed.&lt;/p&gt;

&lt;pre&gt;Mac users$ sudo gem install statmachine
Windows users&gt; gem install statemachine&lt;/pre&gt;

&lt;p&gt;The outcome of this code an instance of Statemachine stored in the variable named &lt;code&gt;vending_machine&lt;/code&gt;.  To use our statemachine we need to send events to it.  This is done by calling methods that correspond to events.&lt;/p&gt;

&lt;pre&gt;puts vending_machine.state
vending_machine.dollar
puts vending_machine.state
vending_machine.selection
puts vending_machine.state&lt;/pre&gt;

&lt;p&gt;That&amp;#8217;s it for the basics.&lt;/p&gt;

&lt;p&gt;This concludes Part 1 of the lessing.  Next we&amp;#8217;ll learn how to make our statemachine more functional with by adding actions.&lt;/p&gt;

&lt;p&gt;&lt;a href="/articles/2006/11/30/understanding-statemachines-part-2-actions"&gt;Understanding Statemachines, Part 2: Actions&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Fri, 17 Nov 2006 05:25:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:e99b9d85-6e6a-4239-9a74-7763bd8a5b2c</guid>
      <author>Micah</author>
      <link>http://blog.8thlight.com/articles/2006/11/17/understanding-statemachines-part-1-states-and-transitions</link>
      <category>Coding</category>
      <category>Statemachine</category>
      <category>Micah</category>
      <enclosure type="image/png" length="4594" url="http://blog.8thlight.com/files/vending_machine.png"/>
    </item>
    <item>
      <title>"Understanding Statemachines, Part 1: States and Transitions" by Gerry</title>
      <description>&lt;p&gt;thanks! i wasted a good part of yesterday until i found this article.&lt;/p&gt;</description>
      <pubDate>Mon, 02 Jun 2008 17:23:03 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:ac561513-1953-4d54-8d1c-9cd02a112d2d</guid>
      <link>http://blog.8thlight.com/articles/2006/11/17/understanding-statemachines-part-1-states-and-transitions#comment-777</link>
    </item>
    <item>
      <title>"Understanding Statemachines, Part 1: States and Transitions" by Kate</title>
      <description>&lt;p&gt;Nice tutorial, thanks.&lt;/p&gt;</description>
      <pubDate>Thu, 08 May 2008 00:07:40 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:2efd4f49-fdc9-4096-b152-b569c13909e6</guid>
      <link>http://blog.8thlight.com/articles/2006/11/17/understanding-statemachines-part-1-states-and-transitions#comment-768</link>
    </item>
    <item>
      <title>"Understanding Statemachines, Part 1: States and Transitions" by Bil Kleb</title>
      <description>&lt;p&gt;Neat, but you forgot the output&amp;#8230;&lt;/p&gt;

&lt;pre&gt;
waiting
paid
waiting
&lt;/pre&gt;

&lt;p&gt;plus a bunch of warnings if you run it through &lt;code&gt;ruby -w&lt;/code&gt;.&lt;/p&gt;</description>
      <pubDate>Wed, 21 Mar 2007 23:23:11 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:5f154167-d2c6-4a02-ab7f-1e5365b93868</guid>
      <link>http://blog.8thlight.com/articles/2006/11/17/understanding-statemachines-part-1-states-and-transitions#comment-16</link>
    </item>
  </channel>
</rss>
