デザパタのBuildeパターンの使い方がやっとわかった
はてなのnaoyaさんが書いたprototype.js でデザインパターン - Builderを読んだ当時は、デザインパターンっていうのが正直何なのかがよくわからなかったし、このJavaScriptのソースコードで意図していることがわからなかったので
「ふーん、何か便利なんだろうなぁー」
位にしか感じませんでした。
最近になって、デザパタの便利さっていうのが徐々にわかるようになってきてBuilderパターン使うことで自分が今作っているツールのソースもかなりすっきりしたものに仕上げられそうなので、naoyaさんが書いた上記エントリの丸写しに近いけどprototype.js読み込まなくてもOKな形で書いてみた。
※AppendableStringクラスは本来無くっても良いのだろうけど各Builderクラスの記述がスマートになりそうだからこれもそのまま丸写し。
/* Builder.js */ var Builder = function(obj){ this._obj = obj; return this._obj; };//Builder var HTMLBuilder = function(obj){ var _builder = new Builder(obj); this.title = _builder.title; this.str = _builder.str; this.items = _builder.items; this.buffer = new AppendableString(''); }; HTMLBuilder.prototype = { makeTitle : function (title) { this.buffer.append('<h1>' + this.title + '</h1>'); }, makeString : function (str) { this.buffer.append('<p>' + this.str + '</p>'); }, makeItems : function (items) { this.buffer.append('<ul>'); for (var i = 0; i < this.items.length; i++) { this.buffer.append('<li>' + this.items[i] + '</li>'); } this.buffer.append('</ul>'); }, close : function() { this.buffer.append('</body></html>'); }, getResult : function () { return this.buffer.toString(); } };//HTMLBuilder.prototype var JSONBuilder = function(obj){ var _builder = new Builder(obj); this.title = _builder.title; this.str = _builder.str; this.items = _builder.items; this.buffer = new AppendableString(''); }; JSONBuilder.prototype = { /* JSON形式の出力はまだ未実装 */ makeTitle : function (title) {}, makeString : function (str) {}, makeItems : function (items) {}, close : function() {}, getResult : function () {} };//JSONBuilder.prototype var Director = function(builder){ this.builder = builder; }; Director.prototype = { construct:function(){ this.builder.makeTitle(); this.builder.makeString(); this.builder.makeItems(); this.builder.close(); }, getResult:function(){ } };//Director.prototype var AppendableString = function(str){ this.str = str; }; AppendableString.prototype = { append : function (str) { this.str = this.str + str; }, toString : function () { return this.str; } };//AppendableString.prototype
自分が作っているツール(WSH+JScript)で考えるとController的なモノとしてこんな↓感じにして、その中で該当のModelとなるクラス(この↓場合だとUser)とうまく連携させれば上手いこといきそうな感じがしてきた。
var _id = "xxxxxx"; var builder,director,arg ; var _user = new User(_id); if(arg=="html"){ builder = new HTMLBuilder(_user); }else { builder = new JSONBuilder(_user); } director = new Director(builder); director.construct(); builder.getResult();
自分のレベルなんてまだまだだけど、こういうのがわかるようになってくるとプログラミングの面白さ/奥深さっていうのがよくわかるなぁ。