Recently, in the course of creating an media asset manager for my day job, I ran across a very useful micro framework.
https://github.com/jakesgordon/javascript-state-machine/
The author is Jake Gordon. He has a blog, http://codeincomplete.com.
A finite state machine is a common paradigm that's been around in computer science at least since Mealy and Moore. It's defined as an abstract machine that can be in one of a number of finite states.
Think of a stop light. Red, yellow, green. It can only be one of these states at a time. The machine is restricted in regards to which state(s) it can transition to and from. It can move from red to green, but not red to yellow. Green to yellow, but not green to red. Yellow to red but not yellow to green.
The following is a simple programmatic example. Open your developer's console to see messages and errors.
http://www.oonn.us/statemachine-minimalist.html
What state machines are NOT good for. State machines don't replace routes.
I've been building apps at my day job with Backbone.js . A route in Backbone is hash-masrked string in the URL and points to a resource. For example, www.mydomain.com/myapp#comment/1234 would present a view of the comment with the id 1234. Everything after the # is the route - a path to the resource.
Other routes might be
/comments ( a list of all the comments in the app )
/comment/4321 ( displays comment with id of 4321 )
or
/comment/new ( a form to create a new comment )
State machines don't replace routes and describing resources in a RESTful way.
So what are state machines good for?
What I've found is that I often have screens that are to be viewed in sequence. Think of a uploading an image. The initial screen might be an input field that allows the user to choose a file from their computer. Once they hit submit, the upload process begins, and the screen presents a loading bar or indeterminate loader. Once loading has completed, the user gets the message 'Your upload is complete! Upload another!'
So here we have three states:
A. Choosing a file
B. Uploading
C. Upload Complete
and three events that would drive the changes in state:
1. User chooses a file.
2. File is completely uploaded.
3. The user clicks to upload a file.
The initial state is ( A. Choosing a file ). Once the event ( 1. User chooses a file ) occurs the state machine transitions from finite state ( A. ) to ( B. ). And when event ( 2. ) is fired, the state transitions to ( C. ). If event ( 3. ) is initiated by the user, the state machine transitions back to state ( A. ).
Using Jake Gordon's code, the state machine would be initiated something like this:
var fsm = StateMachine.create({
initial: 'chooseFile',
events:[
{ name: 'fileChosen', from: 'chooseFile', to: 'uploading' },
{ name: 'fileUploaded', from: 'uploading', to: 'uploadComplete' },
{ name:'uploadFile', from:'uploadComplete', to: 'chooseFile'}
]
}
As you can see, the constructor takes an array named 'events'. Those events have a 'name', 'from', and 'to' properties. When you need to change the state of your view, you invoke fsm.fileChosen() , for instance. If and only if you are in the state chooseFile will the state machine transition to uploading. In any other state, an error will be thrown.
I'll leave it to you to look at my minimalist example and Jake Gordon's README on github to find out how this can be useful to you.
https://github.com/jakesgordon/javascript-state-machine/blob/master/README.md
https://github.com/jwaggener/State-Machines
The takeaway here is:
- Finite State Machines are great for organizing and controlling your views.
- State machines don't replace routing and describing resources in a RESTful way.
- There's a free state machine for javascript ready to go - https://github.com/jakesgordon/javascript-state-machine/ - so take advantage of it.
Notes:
Stop Light code on github:
Jake Gordon's state machine:
No comments:
Post a Comment