Archive for the 'Strategy Pattern' Category

ActionScript 3.0 Strategy Design Pattern: Under No Conditionals

Strategies Eliminate Conditional Statements

If this entry evokes a sense déjà vu, you’d be half right. It is not another jibe to condemn conditional statements, but instead it is a discovery of another pattern where you can eliminate them. The consequences listed by Gamma, et al for the Strategy pattern includes,

Strategies eliminate conditional statements.

While I am quite familiar with the fact that the State design pattern eschews conditional statements, I was unaware that the Strategy pattern has the same feature. Rather, like everyone else I focused on the dictum, encapsulate the concept that varies when dealing with the Strategy pattern. Here I do not plan to re-hash what we covered in Chapter 11 of our book, but instead I want to look at a simple Strategy design pattern where no conditional statements are used. Also, I want to walk through a thought process when working on a simple application and show how flexible it is because of the Strategy design pattern.

It All Began with a simple MP3 Player

Creating an MP3 player in Flash is something I’ve done often and never gave it a second thought using the NetConnection and NetStream classes. However, recently I was working on one using the Sound and SoundChannel classes. Turning it on and off was trivial, but I learned that unlike the NetStream class, the SoundChannel class has no pause method. (NetStream has both toggle and non-toggle versions of pause methods.) The SoundChannel has a position property that returns the position of the MP3 file currently playing. By passing the position value to a variable and passing it to a play() method as a parameter, the play would resume where it left off. So building a player using either NetStream or SoundChannel is not rocket science.

However, suppose you decide to have a structure that could use either the NetStream or SoundChannel class. To that you might also add whether you wanted the MP3 to play on the NetStream as a progressive download or as streaming audio through Flash Media Server 3. All you have to change is the content of the algorithms to accommodate any of the three versions you envision. Of course you don’t want to dismantle all of the other work if you decide to change the program. You just need to change the algorithms.

The Abstract Architecture of a Strategy MP3 Player

When you get right down to it, you only need four algorithms:

  • Start Play
  • Stop Play
  • Pause Play
  • Unpause Play

Depending on what you have set up in the Client class for a UI and the types of classes you’re using to play the MP3 files, the details of the algorithms will vary, and you may even have a class to organize the Sound/SoundChannel or NetConnection/NetStream methods. For now, though, all I want is architecture to handle starting and stopping play and pause. This will also help reveal the structure of the Strategy design pattern. Figure 1 shows the Strategy pattern that is used in this example:

Figure 1: MP3 Player Strategy Design Pattern

The IPlayer interface is the Strategy portion of the pattern. All of the algorithms go into implementations of IPlayer, and so all we need will be four concrete strategies—one for each of the actions on the MP3 player. For this example, I’ll just use trace() statements to act as stand-ins for actual algorithms.

Context Class

The left part of the class diagram in Figure 1 is the Context participant in the pattern. As shown in the diagram, the Context class holds a reference to the Strategy (IPlayer) participant. That reference to the IPlayer can be seen in the following listing:

?View Code ACTIONSCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
 
package
{
	public class Context
	{
		protected var player:IPlayer;
 
		public function doControl():void
		{
			player.control();
		}
	}
}

Continue reading ‘ActionScript 3.0 Strategy Design Pattern: Under No Conditionals’