実践テスト駆動開発

実践テスト駆動開発 テストに導かれてオブジェクト指向ソフトウェアを育てる (Object Oriented SELECTION)

実践テスト駆動開発 テストに導かれてオブジェクト指向ソフトウェアを育てる (Object Oriented SELECTION)

実践テスト駆動開発を読んだ。サブタイトルは「テストに導かれてオブジェクト指向ソフトウェアを育てる」。TDDの手法そのものだけでなく「オンラインオークションの自動biddingクライアントの作成」という実践テーマを通して、オブジェクト指向ソフトウェアの柔軟性を高めるためのノウハウと、アジャイルやプロトタイピングなどの顧客に提供する価値を高める方法が書いてある。

うまくまとまらなかったのでメモしたところだけ箇条書き的に。

  • 予期せぬ変化を早くつかむためにもフィードバックループは欠かせない

    • 仕事をタイムボックスに分割し、設定された期間中に分析・設計・実装をすませてそれをデプロイする
    • デプロイ後実地からのフィードバックを得る
  • テストを書くことはどこまでやれば作業完了なのかを表すことになるので、不必要なフィーチャを盛り込んでしまうことを防げる

    • テストに書いている要件に不必要なフィーチャが入り込むことは防げないけど、テストに書いてある以上のことはしない
  • ひとつの仕組みで複数の概念を表現すると再利用が難しくなるのでコードの重複が生じる

    • オブジェクトは疎結合・高凝集であれ
  • オブジェクトが意思決定を行うとき、自身の情報かメッセージとともに渡された情報のみを使うことを心がける(デメテルの掟)

    • 例えば、引数で渡されたオブジェクトのメソッドの戻り値に対して何らかのメッセージを送るということは、2つ先のオブジェクトの構造まで知る必要があるので結合度が増してしまう
  • デプロイプロセスなどのあるプロセスを自動化するということは、そのプロセスを理解することと明文化することに繋がるのでお得

  • 先にシステム全体のテストを書くことは事前の設計を完璧にすることではない

    • 最初に決めたことはたいてい間違っているのだから、詳細についてはTDDでシステムを育てながら決めていきたい
    • システム全体のテストが動き始め、フィードバックループが実行されるということが重要(TDDサイクルに火を入れる)
  • テストはそのクラスが何をするかという説明書でもある

    • メソッドのテストをするのではなく振る舞いのテストを書く
    • メソッド名だけではそのクラスが何を実現可能なのか分からない
      • フィーチャが実現されているかの確認に集中することが大事という話だと思うがちょっと極端に聞こえる
      • そもそも実装を知らないと書けないテストの部分はコンポーネントとして切り出せそうだが、持たせるべきフィーチャ以外のものも同じ所で実装しちゃうこともある(時と場合によりという言い訳付きで)
  • 様々なコンテキストに適用できる高凝集なオブジェクトを作る

    • オブジェクトの組み合わせ方を変えるだけでシステムの変更が可能となるように
  • 値型の包括性

    • 複数のフィールドが一緒に使われている時、何らかの構造体が欠けている可能性がある
    • それらのグループに名前をつけてまとめ、値型をシンプルに保つ
  • Javaインターフェースはオブジェクト間のプロトコルとして定義する

    • インターフェースを実装したものはロールを表わす
      • クラスは実装上の詳細であり、他のオブジェクトが知ることではない
      • インターフェースを小さくすることでロールがいっそう明確になる
      • オブジェクト間の暗黙的な結合を最小限に抑え、取替え可能なものとする
  • 設計をいつ変更するのか

    • 既存のコードをコピペすることもあるとき、設計を変えるかどうか、時間との相談だというコンテキストで…

「ちょっと変えただけのコードをコピーして使おうとしている。これは馬鹿馬鹿しいし、時間のむだだ」なのか、「今はこれを修正すべきときではない。まだよくわかっていないのだ」なのか。この方針について、再現可能でシンプルなテクニックは存在しない。スキルと経験が必要なのだ。だから、開発者は自分たちの活動について深く考えるよう習慣づけなければならない。この後のコーディングのために自分たちの時間を投資するもっともよい方法は何か、と。その結果、今までとまったく同じようにやることになるかもしれない。しかし、少なくともそれについて考えてはいるのだ。

(p.179より)

  • 心変わり万歳

    • 前に考えていた知識は、開発プロセスを何度も繰り返して得た今の知識と比較すると間違っていたり明確ではない
    • 知識が不明確な状態で考えた構造は脆いので、既にある構造に合わせるのではなくどんどん変えていく
  • 複雑なテストデータの構築

    • テスト対処のオブジェクトを生成するために必要なオブジェクトがあるとき、オブジェクト生成部分が長くなったりしてテストする振る舞いに関係ない情報でうめつくされる
    • テスト対象のオブジェクトが変わった時にテストも大きく変更する必要があるため、テストが脆くなる
    • オブジェクト生成をテストデータビルダーに任せればオブジェクト生成に関するノイズがなくなり、テストに必要なパラメータの明示が可能となる
  • 4段階のTDDサイクル

    • レッド・レポート・グリーン・リファクタリング
      • レポートは診断メッセージを分かりやすくすること
      • レポートがないとコードをグリーンにすることばかりに気を取られてしまいレッド時のメッセージが分かりにくいと、次にレッドになった時に失敗の意味が分からなくなる