No.3 JavaScriptでの疑似クラス(2)
今回はJavaScriptでのSingletonの実現です。
通常のクラスインスタンス
1 2 3 4 5 6 7 8 9 | var app = function() { this.name = 'MyApp'; this.lang = 'ja' } var myFirstApp = new app(); var mySecondApp = new app(); console.log(myFirstApp == mySecondApp); // false |
このコードの10行目を見て下さい。
このように、通常のインスタンス生成では別々のインスタンスとして生成されてしまいます。
それに、これだとクラスのプロパティが簡単に変更できてしまいますし、 どちらかを変更した時点で
統一性は失われてしまいます。
1 2 3 4 | myFirstApp.name = 'YourApp'; console.log(myFirstApp.name); // 'YourApp'; console.log(mySecondApp.name); // 'MyApp'; |
もちろん、この方が都合がよいということもあるでしょう。
ですが今回は、
- 簡単には変更させたくない
- 変更があれば全体で統一したい
こんなクラスを作りたいときにどのようにすればよいのかの、手法のひとつとして Singletonパターンを紹介したいと思います。
Singleton(シングルトン)
Singletonとは、デザインパターンの一つで、
そのクラスのインスタンスが必ず一つしかできないことを保証することができるものです。
余計なインスタンスを増やしたくないときや、アプリケーション全体で統一したいクラスによく使われます。
今回もクロージャーを使います
変数を隠蔽し、簡単にアクセスできないようにするというのは前回やりましたね。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | function app() { var name = 'MyApp'; return { getName: function() { console.log(name); }, setName: function(newName) { name = newName; console.log(name); } } } var myapp = new app(); myapp.getName(); // 'MyApp' myapp.setName('YourApp'); // 'YourApp' |
これで目標その1 簡単には変更させたくない はクリアです。 ですが、
1 2 3 4 5 6 7 8 | var myapp = new app(); var myapp2 = new app(); console.log(myapp == myapp2); // false myapp.setName('YourApp'); // YourApp myapp.getName(); // YourApp myapp2.getName(); // MyApp |
インスタンスごとに変数が変更できてしまい、目標その2はクリアならずです。
ではどうするか?
ここで使うのがSingletonパターンです。
いきなり複雑になったように見えますが、落ち着いてひとつひとつ見ていきましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | var app = (function(){ var instans, getInstans = function() { name = 'MyApp'; return { getName: function() { console.log(name); }, setName: function(newName) { name = newName; console.log(name); } } }; return function() { if (!instans) { instans = getInstans(); } return instans; } })(); myapp = new app(); myapp2 = new app(); console.log(myapp == myapp2); // true myapp.setName('YourApp'); // YourApp myapp.getName(); // YourApp myapp2.getName(); // YourApp |
まず変数appは即時関数が実行された結果として、instansを返す関数が返されます。
その関数をコンストラクターとして利用しているのですが、ここがポイントです!
1 2 3 4 5 6 | // インスタンスがなければ作る(あれば作らない!) if (!instans) { instans = getInstans(); } // インスタンスを返す return instans; |
クロージャーの仕組みを使うことで、ローカル変数のinstansは保持されます。
こうすることで、返されるオブジェクトは常に同じものとなります。
これで目標その2 変更があれば全体で統一したい もクリアです!
まとめ
2回に渡ってJavaScriptでの疑似クラス、その中でも特にクロージャーの仕組みについて注目しながら進めてきました。
クロージャーの仕組みについて理解は深まりましたでしょうか?
今回はSingletonパターンを紹介しましたが、デザインパターンというのはまだまだたくさんあります。
知っていると便利なものもたくさんありますので、一度調べてみるとよいでしょう。
今回はここまで。
次回はデバックについてです。
Let’s デバッグ!
おたのしみに!