デザインパターン ボーキングパターン

2011.02.14kickbaseActionScript3.0


今回はデザインパターンのうちのひとつ、ボーキングパターンについて解説をします。まず「デザインパターン」そのものについての説明ですが、簡単にいうと「プログラムのコツのようなもの」と思ってください。「○○という問題に対しては、△△という方法を使うと大抵うまくいくよ」というノウハウを、パターン化したものがデザインパターンです。詳しくは多くの先輩方が付言しているのでそちらを参照してください。本ブログでは全てのパターンについて解説をするのではなく、簡単ですぐ使えるものを思いついたときに紹介していこうと思います。

ボーキングパターン : 「あるオブジェクトがnullのときに実行すると、エラーが出てしまう処理」を上手く解決してくれるパターン

以下にソースを見ながら解説していきます。

00 : 問題発生
実装内容としては以下のとおりです。

1.Timerクラスのインスタンスが3秒後にBallクラスのインスタンスを生成
2.ステージをクリックするとステージ中央に円が表示される

これだけの処理ですが、3秒間を待たずにステージをクリックしてしまうと、ballインスタンスが生成されていない(つまりballがnullなので)のでエラーとなってしまいます。
※本例ではデザインパターンを使わずともよりスマートな実装方法がありますが、エラーを出すため意図的にこのような実装をしています

Main

package 
{
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	
	/**
	 * ...
	 * @author kickbase
	 */
	[SWF(width = "640", height = "480", frameRate = "30", backgroundColor = "#ffffff")]
	 
	public class Main extends Sprite 
	{
		//ballを宣言します。まだインスタンス化はしません。
		private var ball:Ball;
		
		public function Main():void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			
			//ステージ設定
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			
			//Timerクラスのインスタンスを生成。3秒後にonTimerCompleteイベントハンドラを実行します。
			var timer:Timer = new Timer(3000, 1);
			timer.addEventListener(TimerEvent.TIMER_COMPLETE, onTimerComplete);
			timer.start();
			
			//ステージににマウスクリックイベントをリスン
			stage.addEventListener(MouseEvent.CLICK, onClick);
		}
		
		private function onTimerComplete(e:TimerEvent):void 
		{
			ball = new Ball();
			ball.x = stage.stageWidth / 2;
			ball.y = stage.stageHeight / 2;
			
			trace("ballはnullではなくなりました");
		}
		
		private function onClick(e:MouseEvent):void 
		{
			/*
			 * 3秒間を待たずにクリックしてしまうと、Ballクラスのインスタンスが生成される前に
			 * addChildが実行されてしまい、エラーが出ます。
			 * 
			 * エラーの内容 : パラメータ child は null 以外でなければなりません。
			*/
			addChild(ball);
			
			//ステージのマウスクリックイベントをリスン解除
			stage.removeEventListener(MouseEvent.CLICK, onClick);
		}
	}
}

Ball

package
{
	import flash.display.Sprite;

	public class Ball extends Sprite
	{
		private var _radius:Number;
		private var _color:uint;
		
		/*--------------------------------------------------------------------------
		 * コンストラクタ
		 *---------------------------------------------------------------------*//**
		 * <p>円を描くクラス(引数を省略すると、半径20、ランダムカラーの円が描画される)</p> 
		 */
		public function Ball(radius:Number = 20, color:uint = 0x0)
		{
			color ||= Math.random() * 0xFFFFFF;
			this._radius = radius;
			this._color = color;
			draw();
		}

		private function draw():void
		{
			with (graphics)
			{
				beginFill(_color);
				drawCircle(0, 0, _radius);
				endFill();
			}
		}
	}
}

01 : ボーキングパターンを用いて解決
直球な解決法です。オブジェクト(ball)がnullだと困る処理の先頭に「オブジェクトがnullなら処理を抜けてね」という一行を書き加えるだけです。この手法、使ったことがある方も多いと思います。「よくやっていたけど、これもデザインパターンのひとつなんだ」と認識することで、より意識的に上手く使うことが出来ると思います。

Main

private function onClick(e:MouseEvent):void 
{
	if (ball == null) return;//ボーキングパターン
	addChild(ball);
			
	//ステージのマウスクリックイベントをリスン解除
	stage.removeEventListener(MouseEvent.CLICK, onClick);
}

サンプルのダウンロード

参考サイト

しっぽ流デザインパターン講座(F-site講演資料)
feb19.jp blog – AS3 で GoF デザインパターン [00] – 目次


ページトップへ