Some examples of the State design pattern

If you’ve ever been sick of writing convoluted if/else statements, this design pattern is a good thing to look into.

One thing it enables you to do in Actionscript — have the same button behave differently, depending on what State the application is in. For example, check out your average Flash video player, like this YouTube video from Crossfit Chesapeake / Wilkes Weightlifting:
http://crossfitchesapeake.com/2009/09/13/wod-mon-91309.aspx

In it’s embedded form, the video has a giant PLAY button with a hit area that covers the width & height of the video. In this example, this button could have three states:

  • State 1:
    If the video is dormant (hasn’t been played since the page loaded), clicking the button plays the video. The play icon graphic is displayed in the dormant State disappears once the button is clicked.
  • State 2:
    If the video is already playing, i.e. the application is in a different State, the same button behaves differently. At this time the play button click handler takes you to the YouTube.com page that originally hosts this video and pauses the embedded video.
  • State 3:
    If you go back to the embedded version of the video which has been paused by the play button’s click handler method (the new window with opened with youtube.com, etc) and click the video (not the navbar at the bottom), the smae “click handler” function from the above functionality resumes video play.

And of course, when the same “click handler” method behaves differently based on the State of the application, it’s an example of polymorphism, one of the 4 main elements of OOP. Here’s a decent definition:

Polymorphism allows two objects to be treated identically, using the same methods, even though the objects implement these methods in quite different ways. It is this concept of “same appearance, different behavior” that gets the 0 word, polymorphism.

There’s another State pattern example in the AS3 port of an open source physics library called Box2DFlashAS3.

The Main.as file, in this case the first file that gets the application going, has a listener that calls a function called update(). Among other things, this function
a) continuously checks for an id variable (altered by the user pressing a keyboard key) and
b) sets a variable of type Test to one of the subclasses of Test, like TestRagdoll (the default example when you run the SWF).

The state machine code is essentially this part of Main.as:

/* ...	*/
switch(m_currId){
	// Ragdoll
	case 0:
		m_currTest = new TestRagdoll();
		break;
	// Compound Shapes
	case 1:
		m_currTest = new TestCompound();
		break;
	// Crank/Gears/Pulley
	case 2:
		m_currTest = new TestCrankGearsPulley();
		break;
	// Bridge
	case 3:
		m_currTest = new TestBridge();
		break;
	// Stack
	case 4:
		m_currTest = new TestStack();
		break;
	// CCD
	case 5:
		m_currTest = new TestCCD();
		break;
	// Theo Jansen
	case 6:
		m_currTest = new TestTheoJansen();
		break;
		
	/* ...	*/
}
/* ...	*/
Advertisements