『レガシーコード改善ガイド』を読もう (あるいは、テストを書こう)
“Working Effectively with Legacy Code” の邦訳『レガシーコード改善ガイド』が出たので、買って読んでいる。原著は数年前に買って読んで、去年は読書会にも参加した本だ。やっぱり日本語でよめるのは良い。まわりのひとにも勧めやすくなった。
本書での「レガシーコード」の定義は、表紙にもあるとおり単純に「テストのないコード」を指す。なので、その「改善」も単に「テストを書く」ことだ。
デザインパターン、YAGNI, テスト
ソフトウェアをずっと書いていると、増えたコードを重く感じるようになる。締切もお金もかかってなかった趣味プログラマだったころはすぐ (いまよりすぐ) くじけて、設計がどうこう、みたいなものに救いを求めた。
最初にふれたのはデザインパターンだった。GoF の原典は難しかったので結城浩さんの本で勉強した。ためにはなったし、いま人と話すときには役に立っているけど、当時書いていたものにポジティブな影響を与えていたかというと怪しい。増えたコードに名前がついているのはやや安心できたけど、まあ、安心と安全はちがう。
ちがうとわかってからしばらくは YAGNI (You Aren’t Gonna Need It) というか、必要最低限で素朴な設計を心がけていた。コード量をちいさくおさえるのと、予測をやめたのと、再利用性信仰から抜けたのは良かったけど、素朴さだけでなにかに勝つのは難しかった。
テストはそのあとだ。YAGNI は eXtreme Programming の用語だそうで、なのでテストとは同時に導入するべきなんだけど、そうはいかなかった。いまは「コードは本番で利用され、テストで再利用される。その二回に耐えられるのが良いコード」くらいの基準で、守れたり、守れなかったりしている。
テストは難しい
実際のところテストは難しい。スタックやリンクリストならテストを書くのも簡単だと思うけど、そこから毎日の仕事には距離がある。
私が最近「Scala には型が」みたいなことをいうのには、テストが書いてなかったり、書きづらかったりするコードを見すぎたのがある。型はテストを代替できないけど、たとえばインターフェースの不一致くらいなら、どんなコードについても検出することができる。
どんなコードについても、というのが重要だ。テストは書く側に設計を要求しすぎるし、かといって、得意なひとが後から書く、というのも難しい。よく、テストを最初に書くとか、テスト駆動開発みたいなことがいわれるのも、テスト無しでつくられたコードにはじめてテストを書くことの困難さを象徴してる気がする。
困難に挑む
『レガシーコード改善ガイド』の著者、Michael Feathers はその困難に挑んでいる。「テストのない」を「レガシー」と直結させるところからして決意は明らかだ。
本書の章のタイトルからして泣ける2部に出てくるコードはどれもリアリティ (遅れているプロジェクトに人を追加することで、継承のことで、コピーアンドペーストのことだ) のある酷さで、対抗する側も private を protected にしてみたり、奥底の if の状況を printf デバッグする代わりにそのクラスに public 変数を足してみたり、理解するためにリファクタリングしてからそれを捨ててみたり、わりと手段を問わない。
良い本だと思う。まず技術的に参考になるし、手段を問わない大戦感には、なんというか、熱意がある。
私の多少のテスト好きは、前に職場にいたひとの影響が強い。入社してしばらくして (big bang rewrite をあきらめたあたりで) そのひとは自動テストを書きはじめた。独自プロトコルで話すクライアントとサーバーをなぜか WEBrick がとりもつそのシステムは、いま思うとやや凝りすぎな気もするし、速くはなかったし、比較関数は assert しかなかったし、私の仮想環境上の Linux で動かすにはちょっと修正が必要だったけど、ともあれ、そこには熱意があった。
そんなことを思い出したりしました。