ザネリは列車を見送った

ブログという名の備忘録

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 に出力されたレポートの内容をアサートする。