CoffeeScript によるデザインパターン(Template Method)
『Rubyによるデザインパターン』をCoffeeScriptで書く試み。
目次
HTMLでレポート出力
まずは、月次報告をHTML出力するレポートジェネレータを作成する。
原書では Ruby の puts メソッドを使用しているので、
JavaScript では実用性は低いかもしれないけど console.log で出力することにする。
Reportクラスを作り、コンストラクタで title と text を設定している。
「@title」はJavaScriptの「this.title」となり、Reportインスタンスのプロパティとして扱える。
同じファイル内で「$ -> new Report().outputReport()」として呼んでいるので
ページロード時にコンソール出力されるが、この箇所も含めて即時関数となるので、
(function() { var Report; Report = (function() { ...[略]... })(); $(function() { return new Report().outputReport(); }); }).call(this);
Reportクラスを別のcoffeeファイルやjsファイルから呼ぶことはできない。
フォーマットによって出力内容を分岐
原書に倣って愚直に分岐させてみる。
CoffeeScriptの場合、switch文は「switch ... when ... else ...」となる。
「class @Report」としているため、今度はグローバルに定義されたReportクラスを外部から呼ぶことができる。
(とはいえ、せっかくCoffeeScriptがスコープを限定してくれているので、多様しないほうがいいと思う)
ページを表示し、コンソールで
「new Report().outputReport("html")」
「new Report().outputReport("plain")」
を実行することで挙動を確認できる。
親クラスで共通処理を、子クラスでフォーマットごとの処理を
Template Method を適用するとこのようになる。
Reportクラスは外部から参照する必要はないため、「@」を外している。
子クラスでそれぞれ実装している outputLine メソッドは、親クラスで定義する必要はない。
もちろん、子クラスにも outputLine が存在しないと、outputReport() を呼んだ時点でエラーとなる。
TypeError: Object #<InvalidReport> has no method 'outputLine'
specs2で単体テスト
こちらの仕掛けを使用して、textarea に出力されたレポートの内容をアサートする。