「やる夫で学ぶTDD」五日目 プログラマにやさしいNEET判定 プログラマより愛をこめて #ytdd

某SIerで if(true == false) のような神コードのインスペクションで廃人化しているやらない夫こと太田先生の「やる夫で学ぶTDD」五日目です。
8
Kenichiro Ota @oota_ken

阿部さん:ふふふ、分かっているじゃない。いい感じだやる夫、尻がパンパンだぜ。 #ytdd

2011-02-09 01:06:35
Kenichiro Ota @oota_ken

阿部さん:そして、次だな。CabinetOffice.isNeetはstaticメソッドだったが、これをインスタンスメソッド化する。 #ytdd

2011-02-09 01:10:39
Kenichiro Ota @oota_ken

阿部さん:一度にはせずに、まずはNeetTestに属性、 private CabinetOffice cabinetOffice;を追加し、setUpで初期化するまでのテストコードを書いて実行だ。#ytdd

2011-02-09 01:12:02
Kenichiro Ota @oota_ken

やる夫:それができたら、各テストメソッドで、CabinetOffice.isNeetとクラス名で呼び出していたのを、cabinetOffice.isNeetに置換してテスト再実行だお。成功するお! #ytdd

2011-02-09 01:13:22
Kenichiro Ota @oota_ken

阿部さん:そして、CabinetOffice.isNeetのstaticを除去し、テスト再実行だ。#ytdd

2011-02-09 01:14:47
Kenichiro Ota @oota_ken

やる夫:もちろん、成功だお。 でも、まだ引数が分かりにくいお。#ytdd

2011-02-09 01:15:03
Kenichiro Ota @oota_ken

阿部さん:そこで、リファクタリング「引数オブジェクトの導入」を使う。isNeetの引数になっていたのはいわば人の属性なので、Personクラスを新設し、そのクラスの属性として、引数となっていた各型と値を持たせる。 #ytdd

2011-02-09 01:16:34
Kenichiro Ota @oota_ken

阿部さん:これもEclipseのリファクタリング機能である「パラメーターオブジェクトの導入」で一気に作ることができる。まあ、今回は手で作ってしまったけどな。 #ytdd http://twitpic.com/3xqo3j

2011-02-09 01:22:58
拡大
Kenichiro Ota @oota_ken

阿部さん:今回は元のテストケースを残しながら、順にリファクタリングしていきたかったので、あえて、Personクラスは手作業で作った。 #ytdd

2011-02-09 01:24:59
Kenichiro Ota @oota_ken

やる夫:何でも、ツールの機能使えばいいってわけじゃないんか。さすが、阿部さんだお! #ytdd

2011-02-09 01:25:25
Kenichiro Ota @oota_ken

阿部さん:そうだな。テストケース自体もリファクタリングしていくのがTDD研究会が考えているTDDらしいって聞いたので、俺もそれに倣ってみたぞ。#ytdd

2011-02-09 01:26:09
Kenichiro Ota @oota_ken

阿部さん:そして、Personクラスを使うテストケースに変えるために、一つ一つのテストメソッドをコピーし、Personクラスを使用するものを作っていき、テストしていく。 #ytdd

2011-02-09 01:27:00
Kenichiro Ota @oota_ken

やる夫:こんな感じかお?一気にテストケースが分かり易くなったお。何をセットしてテストしているのかがテストメソッドだけで、分かるようになったお! #ytdd http://twitpic.com/3xqqjh

2011-02-09 01:30:39
拡大
Kenichiro Ota @oota_ken

阿部さん:とうぜん、まだ、CabinetOffice.isNeet(Person)はないから、クイックフィックスで作って、まあ、ナイーブやるなら、return falseから行くが、ここはすでにBooleanのisNeetがすでにあるので、それを再利用しよう。 #ytdd

2011-02-09 01:32:53
Kenichiro Ota @oota_ken

やる夫:できたお!これでテスト実行だお!成功だおー!! #ytdd http://twitpic.com/3xqrv8

2011-02-09 01:34:59
拡大
Kenichiro Ota @oota_ken

阿部さん:アーッ!!!いいぞ。同じようにして、テストメソッドをすべて、cabinetOffice.isNeet(isNeet(Person)を使ったものに変えていく。 これで、最初のものよりはずいぶん、テストケースもクラスも分かり易くなっただろう。 #ytdd

2011-02-09 01:37:06
Kenichiro Ota @oota_ken

阿部さん:ただしだ、何かを得るためには何かを失わねばならん…つまり、等価交換の法則だ。 #ytdd

2011-02-09 01:38:13
Kenichiro Ota @oota_ken

やる夫:とうかこうかんのほうそく? #ytdd

2011-02-09 01:38:25
Kenichiro Ota @oota_ken

阿部さん:「機能の横恋慕」をしており、つまり、よくある業務アプリのなんちゃってオブジェクト指向の実は単なる構造化というアンチパターンだ。 #ytdd

2011-02-09 01:41:48
Kenichiro Ota @oota_ken

やる夫:でも、メンタルモデル的にはそうおかしくないお?ニートの定義は内閣府が知っているというのは自然だお。 #ytdd

2011-02-09 01:42:42
Kenichiro Ota @oota_ken

阿部さん:そうだな。ただ、これはJavaのようなナイーブなオブジェクト指向と手続き型のハイブリットだから問題になるのであって、たとえば、Rubyなら、Neetの判定をモジュールとして定義し、CabinetOffice.isNeet(Person)の中でmix-inして #ytdd

2011-02-09 01:44:06
Kenichiro Ota @oota_ken

阿部さん:判定させるとかすると、より自然な形になり、かつCabinetOfficeがPersonを知りすぎているということもなくなる。Scalaのtraitを使っても同様なことはできる。つまり、ナイーブなオブジェ区指向のパラダイムを組み合わせることのよって、 #ytdd

2011-02-09 01:45:43
Kenichiro Ota @oota_ken

阿部さん:オブジェクト指向のアンチパターンを回避すると同時に、メンタルモデルとの自然な一致も実現できることになる。まあ詳しくは、DCIアーキテクチャー http://bit.ly/h9i8re を勉強してほしいのだが、そこはかなり上級編だな。 #ytdd

2011-02-09 01:47:26
Kenichiro Ota @oota_ken

阿部さん:今回はそこまで考えなくてもいいだろう。 #ytdd

2011-02-09 01:47:39
Kenichiro Ota @oota_ken

やる夫:途中だけど、新しくなったNEET判定のクラス図書いてみたお。 http://twitpic.com/3xomr3 #ytdd

2011-02-09 01:48:31
拡大