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

状態をクラスにし、何通りかの状態のクラスの中で、状況に応じて実行するメソッドを変えるデザインパターン。

構成は Strategy パターンとほぼ一緒だけど、目的が違うらしい。

Strategy はアルゴリズムをカプセル化して、それらを交換可能にするパターンで、State は状態を表すオブジェクトを導入する事で、オブジェクトの内部状況が変化したときにオブジェクトが振る舞いを変えられるようにしたパターン。

通信というオブジェクトに対しての「状態」=未接続、接続中、確率中、切断中など。は、ライフサイクル中の外部イベントにおいて、別の「状態」に遷移していくもので、その都度別の状態に入れ替わる事が前提になります。

ActionScript: IState.as

package jp.feb19.gof.state
{
	public interface IState
	{
		function handle():void;
	}
}

ActionScript: Context.as

package jp.feb19.gof.state
{
	public class Context
	{
		private var _state:IState;
		
		public function Context()
		{
		}

		public function get state():IState
		{
			return _state;
		}

		public function set state(value:IState):void
		{
			_state = value;
		}

		public function request():void
		{
			trace("Would you marry me?");
			state.handle();
		}
	}
}

IState 実装クラス

ActionScript: StatePoor.as

package jp.feb19.gof.state
{
	public class StatePoor implements IState
	{
		public function StatePoor()
		{
		}
		
		public function handle():void
		{
			trace("NO!");
		}
	}
}

ActionScript: StateRich.as

package jp.feb19.gof.state
{
	public class StateRich implements IState
	{
		public function StateRich()
		{
		}
		
		public function handle():void
		{
			trace("YES!");
		}
	}
}

ActionScript: StateTest.as

package jp.feb19.gof.state
{
	import flash.display.Sprite;
	
	public class StateTest extends Sprite
	{
		public function StateTest()
		{
			super();
			
			var context:Context = new Context();
			
			var rich:StateRich = new StateRich();
			var poor:StatePoor = new StatePoor();
			
			context.state = rich;
			context.request();
			
			context.state = poor;
			context.request();
		}
	}
}

出力

Would you marry me?
YES!
Would you marry me?
NO!

if / switch を使わないように出来る・・ってことらしい。すごくたくさんの状態が考えられる状況やクラスを分離する事が出来るところがいいのかも。