Singleton Pattern

Update [20060309]: この記事は id:reinyannyan:20060309:p1 でアップデートされました


こちらの記事 id:naoya:20050813:1123924312 を読んで、JavaScript における Singleton クラスの実装について、しばらく考え込んでみました。

結局のところ、メソッド側でいくら工夫をしても、新たに new でインスタンスを生成されてしまう可能性を排除するのは至難の業であると。

そこで、最初から new できないようにしてしまえばいい、と考えました。以下、prototype.js*1 の利用を前提とした話になります。まず、1行目:

var Singleton = Class.create();

JavaScript において、new によってインスタンスが生成されるのは constructor と呼ばれる Function オブジェクトだけなんですよね*2
そしてこの、Class.create() が返すものは実際には関数(Function オブジェクト)に他なりません。そこで、2行目以降は次のようにします:

Singleton =
{

通常のクラス定義で Singleton.prototype = とする所を Singleton = とすることで、ただのオブジェクトにしてしまうわけです。つまり1行目はクラス定義をしているふりのダミーです(もちろん省略しても構いません)。これで、Singleton は new するとエラーを生じるようになります。続き:

    instance: null,
    getInstance: function ()
    {
	if (!this.instance)
	{
	    var singleton = Class.create();
	    singleton.prototype =
	    {
		initialize: function ()
		{
		    // initialization
		}
		// any methods and/or properties
	    };
	    this.instance = new singleton;
	}
	return this.instance;
    }
};

どうでしょうか。JavaScript ではオブジェクトのメンバーはプライベートにできないので instance プロパティは外から見える形になってしまいますが、実際のコンストラクタは完全にローカル(プライベート)になっているので本来のシングルトンらしいと言えるのではないでしょうか。

参考文献:
http://www.javacoffeebreak.com/articles/designpatterns/

*1:http://prototype.conio.net/

*2:ECMA-262 4章3節4項等参照ください