Categories
Articles

Factory Design Pattern Minimalist Example For Actionscript 3 – Sanders & Cumaranatunge

By Lon (Alonzo) Hosford

This is the minimalist Factory design pattern from chapter 2 of William Sanders and Chandima Cumaranatunge Actionscript 3.0 Design Patterns

Actionscript 3 Design Patterns Learn More

This is an ActionScript project created in Flex Builder and updated to Flex Builder 4. Download the example code. You can build this with the free Flex SDK by using the code in the src folder. Same for Flash CS3 and CS4. You need to create a Flash Document in the src folder and set the document class to Chapter02_Factory_Minimalist_Flash. For your convenience you can download a Flash CS4 ready to go example.

This includes a basic Actionscript debugger console to display tracing statements on stage. Each class sends messages to the console to show their methods working. These messages help you follow the relationships in the Factory design pattern.

Application Class – Chapter02_Factory_Minimalist
This is the client class. The class simply instantiates CreatorA and CreatorB classes and calls the doStuff() method they inherit from the Creator class. The basic idea is that the ProductA and ProductB classes are uncoupled from the client. Uncoupling is a good OOP design principle.

/**
 * Demonstrates a minimalist example of decoupling the client, this file, from the products.
 * The product classes may be modified within the package and the creators maintain the
 * direct interface to the clients.
 * */
package
{
	import com.lonhosford.util.debug.lite.DebugConsole;
	import com.lonhosford.util.debug.lite.DebugMessage;
	import com.lonhosford.util.debug.lite.Debugger;
	import com.lonhosford.util.debug.lite.DebuggerEvent;

	import flash.display.Sprite;

	import example.CreatorA;
	import example.CreatorB;

	// {SET STAGE SIZE AND SPEED HERE}
	[SWF(width=500, height = 300, frameRate = 30)]

	public class Chapter02_Factory_Minimalist extends Sprite
	{
		private var debugConsole:DebugConsole = DebugConsole.getInstance();
		private static const backgroundColor:Number = 0xffffff;
		private static const backgroundBorderColor:Number = 0x666666;
		private static const backgroundBorderWidth:Number = 2;

		public function Chapter02_Factory_Minimalist()
		{

			stage.addChild(debugConsole);
			debugConsole.width = stage.stageWidth;
			debugConsole.height = stage.stageHeight;

			debugConsole.write("Actionscript 3.0 Design Patterns");
			debugConsole.write("William Sanders & Chandima Cumaranatunge");
			debugConsole.write("Chapter 2 Factory Minimalist Example");
			debugConsole.write("\n");

			var ca:CreatorA = new CreatorA();
			var cb:CreatorB = new CreatorB();

			ca.doStuff();
			cb.doStuff();
		}
	}
}

Creator Class
This class provides a “factory method” interface to each of the subclasses. The line 16 shows the factoryMethod() method. The method name for the example emphasizes its purpose. The factory method cannot be called from a client class. The method throws an IllegalOperationError to prevent that coding option.

[ad name=”Google Adsense”]
The factoryMethod() method returns a IProduct class. Each Creator subclass will return its own product all having a manipulate() method defined by the IProduct interface discussed later in this post. This Creator class then uses the product class manipulate() method on line 13.

package example
{
	import flash.errors.IllegalOperationError;

	public class Creator
	{
		public function Creator()
		{
		}
		public function doStuff():void
		{
			var product:IProduct = this.factoryMethod(); // this is SubClass CreatorA, CreatorB etc
			product.manipulate();

		}
		protected function factoryMethod():IProduct
		{
			throw new IllegalOperationError("Creator.factoryMethod() - Abstract method. Override in subclass");
			return null;
		}
	}
}

CreatorA Class
This is a class the client classes use. The Creater super class contains the doStuff() method clients use to interact with the product classes.

package example
{
	import com.lonhosford.util.debug.lite.DebugConsole;

	public class CreatorA extends Creator
	{
		private var debugConsole:DebugConsole = DebugConsole.getInstance();
		public function CreatorA()
		{
			debugConsole.write("CreatorA()");
		}
		override protected function factoryMethod():IProduct
		{
			debugConsole.write("CreatorA.factoryMethod() - creating Product1");
			return new Product1();
		}
	}
}

CreatorB Class

package example
{
	import com.lonhosford.util.debug.lite.DebugConsole;

	public class CreatorB extends Creator
	{
		private var debugConsole:DebugConsole = DebugConsole.getInstance();
		public function CreatorB()
		{
			debugConsole.write("CreatorB()");
		}
		override protected function factoryMethod():IProduct
		{
			debugConsole.write ("CreatorB.factoryMethod() - creating Product2");
			return new Product2();
		}
	}
}

[ad name=”Google Adsense”]
IProduct Interface
This interface provides a common manipulate() method for the Creator class, and all its subclasses, in the package. Each product class implements this interface.

package example
{
	public interface IProduct
	{
		function manipulate():void;
	}
}

Product1 Class
This is the worker bee class. It must implement the manipulate() method of the IProduct interface. The Creator class uses this method in its doStuff() method. Remember the doStuff() method is how client classes interact with the products.

package example
{
	import com.lonhosford.util.debug.lite.DebugConsole;

	internal class Product1 implements IProduct
	{
		private var debugConsole:DebugConsole = DebugConsole.getInstance();
		public function Product1()
		{
			debugConsole.write("Product1()");
		}
		public function manipulate():void
		{
			debugConsole.write("Product1.manipulate()");
		}
	}
}

Product2 Class

package example
{
	import com.lonhosford.util.debug.lite.DebugConsole;

	internal class Product2 implements IProduct
	{
		private var debugConsole:DebugConsole = DebugConsole.getInstance();
		public function Product2()
		{
			debugConsole.write("Product2()");
		}
		public function manipulate():void
		{
			debugConsole.write("Product2.manipulate()");
		}
	}
}