前回はコンストラクタパターンについて紹介しました。
今回はモジュールパターンについて紹介します。
モジュールパターン
従来のJavascript以外でのモジュールパターンというのは、クラスにパブリックとプライベートの両方のカプセル化をもたらす方法でした。
しかし、前回Javascriptにはクラスの概念が無いということを書きました。
Javascriptではクラスのような実装をモジュールパターンで再現することができます。
モジュールパターンを使用することで、1つのオブジェクトにパブリック・プライベートなメソッドや変数を取り込み、グローバルから特定の部分を隠蔽できます。
グローバル空間での変数名や関数名の衝突がしづらくなるわけです。
モジュールパターンでは、クロージャを使い変数やメソッドの隠蔽を実現します。
var testModule = (function() {
// カウンタ変数
var counter = 0;
return {
// カウンタをインクリメント
increment: function() {
return ++counter;
},
// カウンタをリセット
reset: function() {
console.log("リセット前の値: " + counter);
counter = 0;
}
};
})();
このモジュールは実行時、即時関数でオブジェクトを返します。
変数counterには直接アクセスすることができません。
このオブジェクトに内包されたクロージャが、プライベート変数の様に振る舞います。
ここではオブジェクトが返されていることが重要です。
testModuleには自動的にオブジェクトが代入されます。
// 使い方
testModule.increment();
testModule.reset(); // リセット前の値: 1
// counter => 0
console.log(testModule.counter); // オブジェクトのプロパティとして存在しないのでうまくいかない
また、プライベート関数も以下の様に定義することができます。
var testModule = (function() {
// カウンタ変数
var counter = 0;
function privateFunc() {
//...
}
function privateFunc2() {
//...
}
return {
// カウンタをインクリメント
increment: function() {
return ++counter;
},
// カウンタをリセット
reset: function() {
console.log("リセット前の値: " + counter);
counter = 0;
},
// プライベート関数をパブリックに公開
publicFunc: privateFunc
};
})();
testModule.publicFunc();
プライベート関数を利用する利点には以下のようなことが挙げられます。
- モジュール内だけで使用できるプライベート関数を定義できる。パブリックなAPI以外は公開されていないため、このプライベート関数は完全にプライベートであるとみなすことができる。
- 関数に名前が付いているため、デバッグ時にどの関数がエラーか特定しやすい。
モジュールパターンの利点
- オブジェクト指向での開発経験のある人にとって、本物のカプセル化よりもわかりやすい。
- モジュールパターンではプライベートデータがサポートされている。(プライベートデータには外からアクセス出来ない。)
モジュールパターンの欠点
- メンバがパブリックであるかプライベートであるかによってアクセス方法が異なるので、可視性を変更する時には、メンバが使われている箇所すべてに変更を加えないといけない。
- オブジェクトに追加されたメソッドからはプライベートなメンバにアクセス出来ない。(先ほどのcounter変数)
- プライベートメンバについての自動化されたユニットテストが作成できない。
- ホットフィックスが難しくなる。
その他
モジュールパターンをより詳しく知りたい方は以下のサイトを参考にしてみてください。
http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html
次回も引き続きその他のパターンについて紹介していきます。
[aside type=”boader”]
「ステップアップのためのJavaScriptデザインパターン入門」記事一覧
- 第1回:デザインパターンとは
- 第2回:コンストラクタパターン
- 第3回:モジュールパターン
- 第4回:リビーリングモジュールパターン
- 第5回:シングルトンパターン
[/aside]