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

一人っ子パターン。インスタンスを生成する場面で使用されるパターンで、そのインスタンスは二つ以上作られないとすることができます。プロジェクトで一つのインスタンスを共有したいときに使われます。

・音を管理しておきマウス効果音を鳴らすためのクラス
・シーン遷移を制御するクラス
・データを格納しておくクラス

これらを実現するためなら static クラスを用意する方法でもいいのですが、Singleton パターンを使った形にしておくと、他のクラスを継承した形にも出来たり、拡張性もあります。

インスタンスの生成はクラス内部で行い、外部からコンストラクタを呼び出さない所がこのデザインパターンの特徴です。

1. getInstance() から呼び出されていない場合はエラーをスローする実装。
feb19.jp blog – AS2とAS3でSingletonクラスを作る

コンストラクタを呼び出した関数が、 getInstance() かどうかのチェックを行っています。

それ以外の関数であった場合はエラーを発生させます。

2. クラスファイル内に、クラスファイル内からでしか呼び出せないクラスを作っておいて、その型だけを通すようにしておくことで、クラス外からの呼び出しを拒絶する実装です。

ActionScript: Singleton.as

package jp.feb19.gof.singleton
{
	public class Singleton
	{
		private static var _instance:Singleton;
		public function Singleton(enforcer:SingletonEnforcer = null)
		{
			if (enforcer == null)
				throw new Error("getInstance() でインスタンスを取得してください");
		}
		
		public static function getInstance():Singleton
		{
			if (_instance == null)
				_instance = new Singleton(new SingletonEnforcer());
			
			return _instance;
		}
		
		public function sayHello():void
		{
			trace("heelloooo.");
		}
	}
}
  
class SingletonEnforcer {}

1, 2 でもどっちでもいいです。

テストクラス

ActionScript: SingletonTest.as

package jp.feb19.gof.singleton
{
	import flash.display.Sprite;
	
	public class SingletonTest extends Sprite
	{
		public function SingletonTest()
		{
			Singleton.getInstance().sayHello();
			
			new SingletonTestChild();
		}
	}
}

ActionScript: SingletonTestChild.as

package jp.feb19.gof.singleton
{
	public class SingletonTestChild
	{
		public function SingletonTestChild()
		{
			Singleton.getInstance().sayHello();
		}
	}
}

出力

heelloooo.
heelloooo.

別に getInstance() という名前でなくてもいいのですが、他のプログラマーが getInstance() という変数名を見たときにこのクラスは Singleton クラスなんだと一目で分かるので、そうすることがいいようです。

ちなみにこの実装だと、マルチスレッドプログラミングではよくないようなので、Java とかでマルチスレッドプログラミングとかする場合は要注意です。ActionScript3.0 は現状マルチスレッドプログラミングできないので関係ないですが。