『レガシーコード改善ガイド』の感想記事

はいどーもレガシーニートのツミオです。
本日は『レガシーコード改善ガイド』の感想記事を書いていきたいと思いますよ。

どんな本か

ページの多くはテストの書き方について割かれています。
テストのためのリファクタリング技術(とツール)やら、単体テストツールやらの使い方も載っています。
言語は主にC++とJavaですが、他の言語もたまーに混じってます。
Javaはほぼほぼ問題なく読めましたが、C++は全く触ったことがなく、ちょっと難解な部分もありました。

レガシーコードとは何か

本のタイトルにもなっている「レガシーコード」とは何でしょうか。
本書ではズバリ「レガシーコードとは、単にテストのないコードです」と書かれています。
本書はわりと古い本なのですが、今でも「レガシーコード」を書いている方は結構いるかと思います(僕もツクールのプラグイン制作ではテスト全然書かないのでレガシーコードですね……)。
テストがない状態でのリファクタリングは「祈りながら進める」しかなく、リファクタリングとは名ばかりでひっそりと振る舞いが変わってしまっているかもしれません(そして気がついたときには公開していて急いでパッチを作成したり……)。
「テストがないコード」でも「テストを書けるコード」なら少なくともコード自体はある程度綺麗だと思うのですが、テストがないコードはたいがい依存関係がひどく、テストも難しいコードでしょう。
こういう事情もあってテストがないコードはレガシーコードと言っているのかなあと思いました。

遅い単体テストはダメ

「テストくらいできらぁ!」と言って、1つの単体テストに1秒もかかるものは論外のようです。
0.1秒以内に終わらせろと本書では書かれていますが、この本の書かれたのがずいぶん古いことを考慮するなら、もう少し早く終わらせるのがいいのかもしれません。
また、本書では以下に当てはまるものは単体テストではないとまで書かれています(なお、これらのテストが悪いと言っているわけではなく、変更を確認するために使う単体テストではないと言っているだけです)。

1.データベースとやり取りする
2.ネットワークを介した通信をする
3.ファイルシステムにアクセスする
4.実行するために特別な環境設定を必要とする(環境設定ファイルの編集など)

単体テストを書くときは僕も気をつけようと思いましたよ。

擬装オブジェクト

テストをするときに使える擬装オブジェクトの作成方法が色々と紹介されています。
継承を用いたり、インターフェイスを用いたり、はたまたsetアクセサを利用したものやらがあるようです。
「setアクセサなんて使ったら、カプセル化に反するじゃないか」と思うかもしれません。
実際カプセル化には反するのですが、それでも「テストがある方がマシ」というスタンスのようです。
何なら変数をpublicにすることさえアリとのことで、「テストさえあればもっとよい構造にさらに改善することも容易になる」という考えのようです。
最初から最善を目指すよりは、不完全でもテストを最初は用意しましょうねーというのは、創作界隈でよく聞く「とりあえず完成させろ」に近いものがあるなあと思いました。

メモやスケッチ

コードを読むだけでは混乱する場合というのは、まあ結構あると思います。
僕もツクールMVの戦闘関連のプラグインを作成していたとき、コードの流れや相互関係がわからなかったので、図を書きながら進めました(あと他の方が公開してくれているフロー図も参照しましたが、ここで言うメモやスケッチはもう少しラフなもの)。
プログラミング以外でも普通に使えるテクニックなんじゃないかなあと思います。

試行リファクタリング

リファクタリングしようと思ったとき、コードの理解が不完全だと、どのようにリファクタリングを進めたらいいかわからないことがあります。
本書ではこんなとき「試行リファクタリング」を勧めています。
説明を引用します。

まず、バージョン管理システムからコードをチェックアウトしてください。テストを書くことは忘れましょう。メソッドの抽出でも、変数の移動でも、そのコードを理解しやすくするために、あらゆる方法を用いてリファクタリン
グしてください。ただし、そのコードは再びチェックインせずに破棄します。

「これに何の意味が?」と思うかもしれませんが、リファクタリングを進めるとコードへの理解が深まります。
すなわち、試行リファクタリングをおこなったあとでもう一度リファクタリングをすると、次は綺麗にリファクタリングできるかもねーということです。

privateメソッドのテスト方法

よく聞かれる質問の一つとして「どうやってprivateメソッドをテストするのでしょうか?」というものがあるらしいです。
これは僕もずっと疑問に思っていました。
それに対する答えは以下のようなものです。
「どうしてもprivateメソッドをテストしたいのなら、そのメソッドはprivateにすべきではない」
これを読んだとき初めは「はぁ?」となるかと思います。
僕もそうでしたw
ただこの文章で本当に言いたいのは「メソッドをpublicにしてよいかどうかで悩むのは、そのメソッドが別の責務の一部で、本来ならそのメソッドは別のクラスにあるべきだからかもしれない」ということです。
なるほどなあと思いました。

オブジェクト指向以外でもテスト

最近はオブジェクト指向を取り入れている言語が多いため、本書でもオブジェクト指向を用いたコードの改善方法が多く紹介されています。
ですが「レガシーコード」にはオブジェクト指向を扱えないものがあり、そのような環境での「テストできるコードの書き方」にもかなりのページが割かれています。
詳細は書きませんが、プリプロセッサを用いたりリンク結合部を用いたり、いろいろとやり方があるのだなあと思いました。

役立ちそうな言葉も多い

僕は小説を読むとき「カッコイイ言葉」をメモすることが多いのですが、プログラミング関係の書籍を読んでいるときもわりとメモっています。
その中で気になったものをペタペタ貼っておきますね。

・簡潔な見方を明確に述べることには価値がある。それによって何が理想的で何が便宜的なのか理解できる
・「優れたコードは本番環境でもテスト環境でも動く」
・古いC言語のシステムは、大きな1つのオブジェクト
・重複を取り除くことで、コードは自然に開放/閉鎖原則に沿ったものになっていく
・プログラミングとは一度に1つのことを行う技術
・staticメソッドやstatic変数は、本当はクラスの一部ではない

終わりに

かるーい気持ちで買った本だったのですが、かなりボリューミーでした。
理解できない部分もちょこちょこあったので、もう少し成長したら再読したいですね。

ほなそんな感じでまた。
お仕事も募集中ですよ。

フォローする