ActionScript 3 (Flash/AIR): GoF デザインパターン – Factory Method

インスタンスの生成をサブクラスに任せるパターンです。Abstract Factory と違って、生成のみを受け持ち、自身は状態を持ちません。

ActionScript: NotFactory.as

package jp.feb19.gof.factorymethod
{
        import flash.display.DisplayObject;
        import flash.display.Shape;
        import flash.display.Sprite;
        
        public class NotFactory extends Sprite
        {
                public function NotFactory()
                {
                        super();
                        
                        var displayObject:DisplayObject = new Shape();
                        
                        addChild(displayObject);
                }
        }
}

new Shape ではなく Sprite を使いたいとか、色々描画された Shape をおきたいとかの場合にこのパターンを使用してみて、サブクラスを利用するようにします。

ActionScript: Factory.as

package jp.feb19.gof.factorymethod
{
	import flash.display.DisplayObject;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.errors.IllegalOperationError;
	
	public class Factory extends Sprite
	{
		public function Factory()
		{
			super();
			
			var displayObject:DisplayObject = create();
			
			addChild(displayObject);
		}
		
		protected function create():DisplayObject
		{
			throw new IllegalOperationError("サブクラスで定義してね");
			return null;
		}
	}
}

ActionScript: FactoryCircle.as

package jp.feb19.gof.factorymethod
{
	import flash.display.DisplayObject;
	import flash.display.Shape;
	
	public class FactoryCircle extends Factory
	{
		public function FactoryCircle()
		{
			super();
		}
		
		override protected function create():DisplayObject
		{
			var shape:Shape = new Shape();
			shape.graphics.beginFill(0xff0000);
			shape.graphics.drawCircle(0, 0, 100);
			shape.graphics.endFill();
			return shape as DisplayObject;
		}
	}
}

ActionScript: FactoryRect.as

package jp.feb19.gof.factorymethod
{
	import flash.display.DisplayObject;
	import flash.display.Shape;
	
	public class FactoryRect extends Factory
	{
		public function FactoryRect()
		{
			super();
		}
		
		override protected function create():DisplayObject
		{
			var shape:Shape = new Shape();
			shape.graphics.beginFill(0xff0000);
			shape.graphics.drawRect(0, 0, 100, 100);
			shape.graphics.endFill();
			return shape as DisplayObject;
		}
	}
}

テストクラス

ActionScript: FactoryTest.as

package jp.feb19.gof.factorymethod
{
	import flash.display.Sprite;
	
	public class FactoryTest extends Sprite
	{
		public function FactoryTest()
		{
			super();
			
			var rect:Factory = new FactoryRect();
			addChild(rect);
			rect.x = 100;
			rect.y = 100;
			
			var circle:Factory = new FactoryCircle();
			addChild(circle);
			circle.x = 300;
			circle.y = 100;
		}
	}
}

Flash でシンボルをリンケージして呼び出すときに凄く似てますね。

Strategy パターン、State パターン、 Command パターンが類似のデザインパターンです。使われる状況は違いますが、単に切り替わるクラスが戦略なのか状態なのかコマンドなのかの違いで、何をオブジェクトとして取り出すかで分類しているぐらいです。