2013-07に参加して来ました。まとめはめんd僕が改めて書くよりも素晴らしいまとめをされている方がいらっしゃるので、いくつか紹介させて頂いて終わろうと思いますwhttp://makopi23.blog.fc2.com/blog-entry-96.htmlhttp://taichiw.hatenablog.com/entry/2013/07/29/003642ペアプロ大会やっぱりTDDBCのいいところは、発表聞いて終わりじゃなくて、実践までがセットになっているところだなーと改めて思いました。僕のペアもなかなか変わったペアだったので、この記事もペアプロの話メインにしようかと。2013というわけで、@razonさんとScalaでペアプロさせていただきました。@razonさんありがとうございます!で、当日書いたコードがこちら。https://github.com/shizone/tddbc201307今回の記事ではこのコードの解説でもしてみようと思います。「やっぱオブジェクト指向はダメだね」というセリフが出たシーンがこのペアプロのハイライトでした。Scalaでやるということで、コーディングスタイルとしてオブジェクト指向に寄るか関数型に寄るか選べるわけです。最初僕らはオブジェクト指向の方を選びました。最初のうちはうまく行ってたのですが、在庫管理を始めたあたりからテスト書くのに「モック必要じゃね」とか「他の機能もいくつか先に実装しないとテスト書けないよね」とかいうオブジェクト指向TDDあるあるにハマり始めて、イライラしてきました。「よし、やっぱり関数で行こう」となったわけです。状態(内部変数)の排除まずはVendingMachineという型をつくります。「class」という名前がついているので紛らわしいですが、これはオブジェクト指向でいうクラスとは全く違うものです。「total」や「stock」という変数は再代入不可能になるので、VendingMachineはimmutableであり*1、状態を持ちません。型VendingMachineは現実世界のオブジェクトのテンプレートとしてのクラスではなく、ある瞬間の自販機の状態を表現するスナップショットとしての単なるデータにすぎません。処理を関数で記述オブジェクト指向の場合は、例えば「10円を入れる」という処理はVendingMachineクラスのメソッドとして表現し、内部変数を書き換えるという実装をするわけですが、関数型の場合は、処理を行う前のスナップショットから処理を行った後のスナップショットを計算する関数を記述します。「関数を返す関数」を作ることもできるので、「コインを入れる」という関数はこのような表現が可能です。関数のテストを書くちょっとその前に、テストを書きやすくする補助関数も作っておきます。初期状態を取得するinitと、パイプライン演算子*2を。パイプライン演算子の実装の方はちょっと高度なので今回は詳しく書きませんが、よく見るパターンです。classを使って、メソッド「|>」を記述しています。意味合い的にはただ単に関数適用の記述を楽にするだけのものです。f」と書けるようにするだけ。h」となって素敵です。ここまで準備すると、テストコードがどうなるか。「初期状態の自動販売機に100円玉を入れて、次に10円玉をいれると、投入金額合計は110円になる」というテスト、こうなります。(当日はScalaTestを使いましたが、僕はSpecs2の方が慣れてるのでSpecs2式に書きます)まとめ「TDDBC当日のペアプロ大会で、Scala組はこんな感じのコードを書いてました」という紹介をしてみました。一部Scala黒魔術が顔を見せたりしてはいるものの、簡潔で読みやすいテストコードが書けるよーという様子を感じて頂ければと思います。Testと相性がいい」という僕の持論もあるのですが、その話はまた今度。ちなみにScalaではMap型も(特にmutableなものを使うことを明示しない限り)immutableです。パイプライン演算子はもともと「F#」由来の素敵な演算子です。いいページが見つからなかったのでテキトーにググってくださいwちなみにScalazに実装されています。本記事の内容は「僕の個人的な考え」であって、正解とは限りません。