お題その5、その6
紙面の都合で割愛しますが、ぜひ挑戦してみてください。
お題その5:入力として選手のリストを受け取り、打率の順位を計算できること。
打席数が0の選手と打率が0割の打者では、打率0割の打者の方が上位に来ること。
お題その6:入力として選手が所属しているチームの消化試合数を追加で受け取り、打席数が消化試合数×3.1 を少数第一位で四捨五入した数以上の選手とそうでない選手で順位を分けて計算できること。
List<野球選手>
を引数に渡して、ソートした結果を返してもらえばよさそうですが…
- 野球選手オブジェクトを打率で比較して並べ替えるには、野球選手オブジェクトが打撃データを持っている必要があります。
-
List<野球選手>.Sort()
を使うのは、よくありません。野球選手の大小関係が打率だけで決まるというのは、おかしな話です。List<野球選手>.Sort(Comparison)
かList<野球選手>.Sort(IComparer)
を使うことを検討してみましょう。 -
ソートするメソッドの外部設計は、(ソート自体のロジックは組み込みのもので信頼がおけるとするなら)次のパターンを考えればよいでしょう。
・引数のList<野球選手>
がnull
・選手が0人
・選手が1人
・選手が2人 × 大小比較のパターン
※3人以上は、組み込みのソートロジックを信頼してテスト不要。心配なら、もう一人追加して3人の場合のテストケースも実施すれば、帰納法的にOKと確信できる(ただしケース数は等比級数的に増加する)。なお、0人・1人のケースは、テストファーストのためにはおそらく不要。
※Comparison<野球選手>
デリゲートとして使う比較関数を公開することにして、それもテストファーストで作るのであれば、上記の「大小比較のパターン」は考慮しなくてもよくなる。 -
同じ順位の選手が複数いたとき、正しく順位を表示するにはどうしたらよいでしょう。返値が
List<野球選手>
ではうまくいかないかもしれません(最初はシンプルにList<野球選手>
を返すようにしておいて、後から考えればよいでしょう)。 - 同率順位のテストケースには、同率2位の選手2名を含む計4人のリストが必要です。結果が[1位, 2位, 2位, 4位]にならないといけません。
まとめ
- TDD = テストファースト + リファクタリング
- テストファースト:RED → GREEN
- テストファーストは、事前にメソッドの外部設計を検討しておくとうまくできる。
- 実際の開発では、テストファーストの原則に縛られすぎないこと。不安を解消するためのテストや、仕様を明確にするテストなども、必要に応じて書く。(ただし、不必要なテストを増やし過ぎると、変更するときの手間が大変になります。ほどほどに!)
- リファクタリングはごく簡単なものを少しだけ紹介した。詳しくはMartin Fowler著「リファクタリング―プログラムの体質改善テクニック」を参照。
参考資料
「仮実装」などのTDD用語は、TDDの原典である「テスト駆動開発入門」(Kent Beck 著)に拠りました。そのほか、本文中で紹介できなかった資料を挙げておきます。
- 『テスト駆動開発入門』 Kent Beck 著、長瀬嘉秀・テクノロジックアート 訳、ピアソンエデュケーション、2003年9月
- 「C# 2008 Express + NUnit 2.5 で、 初めてのテストファースト Step by Step」(筆者サイト)
- Tech・Ed japan 2009 ライトニングトーク:「TDD とメソッドの外部設計 ~ テストファーストの秘訣」(筆者によるライトニングトークのWebキャストとスライド資料)
また、筆者のサイトに「TDDに関する書籍」を挙げてありますので、参考にしてください。