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

沢山のオブジェクトで構成されるオブジェクトを生成するときに利用すると便利です。いくつものオブジェクトの組み合わせの「セット」を、Abstract Factory を継承したサブクラスでまとめておくと、別のセットにはまた Abstract Factory のサブクラスを作成してどんどん作成していくことが出来ます。

メインクラス側では AbstractFactory を使うだけなので、別のセットを使用したい場合はごそっと入れ替えることができます。

スキンセットをごそっと入れ替える際や、ゲームのキャラクター管理などたくさんのデータをいっぺんにセットとして扱う際に便利です。

ActionScript: Factory.as

package jp.feb19.gof.abstractfactory
{
	public class Factory
	{
		protected var _skinSet:SkinSet;
		
		public function Factory(skinSet:SkinSet)
		{
			_skinSet = skinSet;
		}
		
		public function setAll():void
		{
			this.setHomeButton();
			this.setBackgroundImage();
		}
		
		protected function setHomeButton():void
		{
			
		}
		
		protected function setBackgroundImage():void
		{
			
		}
	}
}

ActionScript: HomeButton.as

package jp.feb19.gof.abstractfactory
{
	public class HomeButton
	{
		public function HomeButton()
		{
			
		}
		public function toString():String
		{
			return Object(this).constructor;
		}
	}
}

ActionScript: BackgroundImage.as

package jp.feb19.gof.abstractfactory
{
	public class BackgroundImage
	{
		public function BackgroundImage()
		{
		}
		public function toString():String
		{
			return Object(this).constructor;
		}
	}
}

ActionScript: SkinSet.as

package jp.feb19.gof.abstractfactory
{
	public class SkinSet
	{
		private var _homeButton:HomeButton;
		private var _backgroundImage:BackgroundImage;
		
		public function SkinSet(homeButton:HomeButton = null, backgroundImage:BackgroundImage = null)
		{
			_homeButton = homeButton;
			_backgroundImage = backgroundImage;
		}
		
		public function get homeButton():HomeButton
		{
			return _homeButton;
		}
		
		public function set homeButton(value:HomeButton):void
		{
			_homeButton = value;
		}
		
		public function get backgroundImage():BackgroundImage
		{
			return _backgroundImage;
		}
		
		public function set backgroundImage(value:BackgroundImage):void
		{
			_backgroundImage = value;
		}
		
		public function toString():String
		{
			return "current skin set:\n" + _homeButton.toString() + "\n" + _backgroundImage.toString() + "\n";
		}
	}
}

実装系クラス

ActionScript: CuteSetFactory.as

package jp.feb19.gof.abstractfactory
{
	public class CuteSetFactory extends Factory
	{
		public function CuteSetFactory(skinSet:SkinSet)
		{
			super(skinSet);
		}
		
		override protected function setHomeButton():void
		{
			_skinSet.homeButton = new CuteHomeButton();
		}
		
		override protected function setBackgroundImage():void
		{
			_skinSet.backgroundImage = new CuteBackgroundImage();
		}
	}
}

ActionScript: CuteHomeButton.as

package jp.feb19.gof.abstractfactory
{
	public class CuteHomeButton extends HomeButton
	{
		public function CuteHomeButton()
		{
			super();
		}
		override public function toString():String
		{
			return super.toString();
		}
	}
}

ActionScript: CuteBackgroundImage.as

package jp.feb19.gof.abstractfactory
{
	public class CuteBackgroundImage extends BackgroundImage
	{
		public function CuteBackgroundImage()
		{
			super();
		}
		override public function toString():String
		{
			return super.toString();
		}
	}
}

ActionScript: CoolSetFactory.as

package jp.feb19.gof.abstractfactory
{
	public class CoolSetFactory extends Factory
	{
		public function CoolSetFactory(skinSet:SkinSet)
		{
			super(skinSet);
		}
		
		override protected function setHomeButton():void
		{
			_skinSet.homeButton = new CoolHomeButton();
		}
		
		override protected function setBackgroundImage():void
		{
			_skinSet.backgroundImage = new CoolBackgroundImage();
		}
	}
}

ActionScript: CoolHomeButton.as

package jp.feb19.gof.abstractfactory
{
	public class CoolHomeButton extends HomeButton
	{
		public function CoolHomeButton()
		{
			super();
		}
		override public function toString():String
		{
			return super.toString();
		}
	}
}

ActionScript: CoolBackgroundImage.as

package jp.feb19.gof.abstractfactory
{
	public class CoolBackgroundImage extends BackgroundImage
	{
		public function CoolBackgroundImage()
		{
			super();
		}
		override public function toString():String
		{
			return super.toString();
		}
	}
}

テストクラス

ActionScript: AbstractFactoryTest.as

package jp.feb19.gof.abstractfactory
{
	import flash.display.Sprite;
	
	public class AbstractFactoryTest extends Sprite
	{
		public function AbstractFactoryTest()
		{
			super();
			
			var skinSet:SkinSet = new SkinSet();
			
			var factory:Factory = new CoolSetFactory(skinSet);
			factory.setAll();
			trace(skinSet);
			
			factory = new CuteSetFactory(skinSet);
			factory.setAll();
			trace(skinSet);
		}
	}
}

出力

current skin set:
[class CoolHomeButton]
[class CoolBackgroundImage]
 
current skin set:
[class CuteHomeButton]
[class CuteBackgroundImage]
 

Builder との違いがイマイチよく分かりません。入れ替える主眼の AbstractFactory と、作ること主眼の Builder ってことでしょうか。