このシリーズでは7月に刊行される翻訳書「レガシーコード改善ガイド（Working Effectively With Legacy Code）」に書かれている内容から、重要なトピックを取り上げて紹介していきます。今回は、レガシーコードの定義やテストの重要性、そしてその考えに基づくこの本の本来の目的などを説明します。

「レガシーコード」とは何か

最初に1つ質問です。皆さんは、「レガシーコード」と聞いて何を想像するでしょうか？ 多くの方はCOBOLなどで書かれたメインフレームで動くコードを真っ先に思い浮かべるのではないかと思います。しかし、本当にそれだけでしょうか？

ここでは「レガシーコード」という言葉を『何年も前に誰かが作り、内容が複雑で何をしているのかよく分からず、まともな仕様書もない』というコードを指すものとします。そう考えると、必ずしもメインフレームだけの話ではなくなります。この記事を読んでいる皆さんなら、そのようなコードを少なからず目にしていることでしょう。

現在の業務システムは、Java EEや.NETなどの基盤上に構築される、いわゆるオープンシステムが主流になっています。このようなオープンシステムであっても、構築されてから既に5年以上経過していることが珍しくなく、何度も手が加えられたコードは混乱し、簡単な機能追加であっても多くの労力と時間を必要とする状態になってしまっている場合があります。こういうシステムのコードも、立派な「レガシーコード」と呼ぶことができそうです。

原書「Working Effectively With Legacy Code」

さて、ここに『Working Effectively With Legacy Code』というタイトルの本があります。タイトルは「レガシーコードを効果的に改善する」といった意味で、既存の混乱したコードの品質を少しずつ改善しながら変更する方法を説明しています。

IT関連の技術書は数多くありますが、こうしたテーマを取り上げたものはほとんどありません。私は原書を読んで、オブジェクト指向言語による業務システム開発が一巡した現在、まさに多くのプログラマが求めているテーマを取り上げた良書であると感じました。

そしてちょっとした縁があって、しばらく前からこの本を共同で翻訳することになったため、原書を隅から隅まで読むことになりました。この本は近々『レガシーコード改善ガイド』というタイトルの翻訳書として、翔泳社より刊行される予定です。このCodeZineの連載では、翻訳書の刊行に先駆けて、そこに書かれている重要なトピックを少しずつ紹介しながら、本書のすばらしさを皆さんにお伝えすることにチャレンジしてみたいと思います。

翻訳書「レガシーコード改善ガイド」トピック

テストのないコードがレガシーコード

さて、この書籍では「レガシーコード」を次のように定義しています。

レガシーコードとは、単にテストのないコードである

この定義を見て、皆さんはどう感じたでしょうか。現実問題として、なかなか厳しい定義です。私がこれまで見てきたシステムは、きれいな設計やコードだったとしても、テストまでしっかり揃っているものは少なかったからです。この定義だと、世に存在する多くのプログラムがレガシーコードと認定されてしまいそうです。

著者は上記のように定義した理由を、次のように説明しています。

テストのないコードは悪いコードである。どれだけうまく書かれているかは関係ない。どれだけ美しいか、オブジェクト指向か、きちんとカプセル化されているかは関係ない。テストがあれば、検証しながらコードの動きを素早く変更できる。テストがなければ、コードが良くなっているのか悪くなっているのかが本当には分からない。

これを見て「きれいな設計やコードなら、変更は簡単なのでは？ 」と感じる方がいるかもしれません。設計やコードをきれいにすることは重要ですし、そのための技術書もたくさん書かれています。ですが、それだけでは不十分なのです。その理由を、本書に書かれている対照的な2つの変更方法を用いて説明してみます。

「編集して祈る」か、「保護して変更する」か

皆さんは、システムを変更する際にどのような方法をとりますか？ この本では、システム変更の方法を大きく2つ、「編集して祈る」と「保護して変更する」に分けています。著者は「保護して変更する」方法を取るべきだと考えており、「編集して祈る」と対比させて、その重要さを説明しています。

1）「編集して祈る」

「編集して祈る」は、既存のコードを注意深く調べながら修正する方法です。この場合の手順を想像してみましょう。まずはステップごとに何が起こるかを明確に理解し、コード変更の影響範囲を把握します。次に、時間をかけて注意深くコードを書き、コード変更がすべて終わったら、祈る気持ちで動かしてみます。その結果は「あれ？ 変更箇所は大丈夫だけど……別の機能が動かなくなってしまった……」。

既存のコードを変更した経験のある方は、このような状況に遭遇したことがあるのではないでしょうか。この状況は、きれいな設計やコードでも実に簡単に起こります。スパゲッティコードに比べれば理解しやすいとはいえ、今度は設計やコードの意図を理解するだけの技術力が求められます。理解していなければ、コード変更の影響範囲を把握できず、また手を加えてよい箇所も分かりません。次第にきれいな設計やコードは壊れていき、分かりづらくなっていきます。コードを変更するということはそれだけ難しいことなのです。

「注意をより多く払ったからといって、必ずしもそれに比例して安全性が向上するとは限らない」と著者は強く述べています。既存コードに手を入れる際には、「残りの振る舞いを変えずに済ませることができるかが重要」ですが、注意深いだけでは、他の部分に影響が及んでいるかどうかまでは最後に動かしてみないと分かりません。どんなに注意深く進めても、結局は「編集して祈る」ことになってしまいます。

2）「保護して変更する」

もう1つの「保護して変更する」は、テストを用意したうえで既存のコードを修正する方法です。コードの変更が難しい理由をよく考えてみると、テストがあればコードの変更が簡単になるという、意外と単純なことに気がつきます。もし、変更している最中にうまく変更できているかどうか、他の部分に影響が及んでいないかどうかを確認する手段があったとしたらどうなるでしょうか。その場合は、少し変更をして、大丈夫かどうかを確認して、また少し変更をして、という作業を繰り返しながら進めることが可能になります。

少しずつ前進すれば、ステップごとの明確な理解や注意深くコードを書かなくても影響範囲が把握できますし、すぐに間違いが分かります。まるで、「空中ブランコの転落防止の網」のようです。転落防止の網とはテストのことです。テストがあればすばやくフィードバックが得られ、より細かい部分に注意を払いながら、修正を進めることができます。

コードは保護して変更しなければ安全ではありません。保護して変更するためにはテストが必要になります。テストのないコードはレガシーコードなのです。