somemo's diary

プログラマ、雑記、プログラミング関係はLinkから、数式はこっちでまとめていることが多い

【TDD】テスト駆動開発入門13章完了

時間がだいぶ立ちました・・・。ようやく13章が終了したのでメモしておきます。

前回仮実装した通貨を変換するメソッドreduceと、そのテストコードに重複があるのでリファクタリングすることから始まります。

// 仮実装
Money::dollar(10);

// テストコード
$five = Money.dollar();
$five->plus($five);

直感的な感想としては、思いつかなかった!です。plusメソッドの$10通貨を返すというところではなく、通貨の合計式として返すというところに焦点をあてています。

通貨の合計式 - Sum

新しくSumクラスを作成します。合計を表す式が示すように、「被加数」「加数」という通貨のメンバ変数を持つようにします。もちろん式として扱えるようにするため、Expressionを実装します。

最後に、銀行に合計式を渡して通貨に変換してもらいます。ここで問題が発生しました・・・というより自分の知識不足です。

書籍どおり実際にJavaJUnitを使ってみましたところ、当たり前ですが問題ありません。PHPでは、このままではテストの実行すらできません。

理由は、PHPでは継承関係にないほかのオブジェクトのメンバ変数(private,protected)を参照することはできないためです。では、なぜJavaではできたのか?

Javaでは、同じパッケージに属するクラスのメンバ変数を自由に参照できるためでした・・・。解決法として、Money#amountに対するgetterを作成しました。

getter amount()

getterメソッド用のテストを作成します。

/**
 * amountのgetterテスト
 */
public function testAmountGetter() {
    $five = Money::dollar(5);
    $this->assertEquals(5, $five->amount());
}

amount()メソッドはないので、怒られます。amount()を作成します。振る舞いは明確なので、単純にamountを返すだけです。

/**
 *
 * 通貨の金額を取得する
 */
public function amount() {
    return $this->amount;
}

式の変換を実装する

現在存在する式は、MoneyとSumの2種類です。よって、クラスが違うものを銀行(Bank)に任せても判別をしてから実行しなくてはいけません。

2つは式なので、変換メソッドを定義して各式で実装します。これにより、コードがすっきりして責任をそれぞれの式に振り分けることができました。

まとめ

まだリファクタリング完成ではないです。書籍どおりの言語を使わないことで二つの違いが分かり勉強になりました・・・次はRubyでやりたいなぁ。