このブログでのデザインパターン連載も5回目になってやっと連載らしくなってきました。
引き続き今回はシングルトンパターンを紹介します。
シングルトンパターン
オブジェクトのインスタンスの生成を1つに制限する、というのがシングルトンパターンです。
手軽に実装するには以下のようにオブジェクトリテラルを使用することで実装できます。
var Singleton = {
prop: 1,
another_prop: 'value',
method: function() {…},
another_method: function() {…}
};
しかし、これではプライベート・パブリックの区別ができません。全てのプロパティ、メソッドにアクセスできてしまいます。
シングルトンパターンの常套手段としては、インスタンスが作成されていなかったら作成し、すでに作成されている場合はそのインスタンスを返します。
サンプルとしてシンプルな時計の実装例を見ます。
var watch = (function() {
function Watch() {
this.date = null;
this.timer = null;
this._init();
}
Watch.prototype._init = function() {
var self = this;
this.week = ['日', '月', '火', '水', '木', '金', '土'];
this.update();
this.timer = setInterval(function() {
self.update();
}, 1000);
};
Watch.prototype.update = function() {
this.date = new Date();
this.render(this.formatter(this.date));
};
Watch.prototype.render = function(format) {
console.log(format);
};
Watch.prototype.formatter = function(date) {
var month = date.getMonth() + 1,
day = date.getDate(),
weekday = this.week[date.getDay()],
after = date.getHours() < 12 ? '午前' : '午後',
hour = date.getHours() > 12 ?
('0' + (date.getHours() - 12)).slice(-2) :
('0' + date.getHours()).slice(-2),
minutes = ('0' + date.getMinutes()).slice(-2),
seconds = ('0' + date.getSeconds()).slice(-2);
return month + '月' + day + '日(' + weekday + ') ' + after + hour + ':' + minutes + ':' + seconds;
};
// インスタンスの保存場所
var instance;
// 静的な変数やメソッドの列挙
var _static = {
name: 'Watch',
// インスタンスを取得するメソッド
// シングルトンオブジェクトのインスタンスを返す。
getInstance: function(options) {
if (instance === undefined) {
instance = new Watch();
}
return instance;
}
};
return _static;
})();
watch.getInstance().update();
Demo
(ブラウザのコンソールを開いて確認して下さい)
利点
原則としてオブジェクトは1つしか作られないので、グローバル名前空間を汚染されることはなくなります。
欠点
シングルトンがある場合、往々にして、システム内のモジュール同士が密結合していたり、
ロジックがコードベースのあちこちに散らばっていることを示します。
隠れた依存関係があること、複数のインスタンスを作成するのが困難なこと、依存関係をスタブで表現しにくいことなど
様々な問題により、シングルトンのせいでテストがより難しくなることがあります。
※Javascriptにおけるテストについては追々記事にしようと思います。
[aside type=”boader”]
「ステップアップのためのJavaScriptデザインパターン入門」記事一覧
- 第1回:デザインパターンとは
- 第2回:コンストラクタパターン
- 第3回:モジュールパターン
- 第4回:リビーリングモジュールパターン
- 第5回:シングルトンパターン
[/aside]