「レガシーコードからの脱却」第Ⅰ部のまとめ

はじめまして、@kzkhmdです。
普段は、電子機器メーカーで組み込みソフトウェアエンジニアをしています。

私が働く現場では、長年継ぎ足して作られてきた秘伝のタレのようなコードがたくさんありますが、それらのコードは読むのも変更するのも難しいコードであることがほとんどです。
このようなコードの保守に疲弊していたとき、「[レガシーコードからの脱却](https://www.oreilly.co.jp/books/9784873118864/)」という本に出会いました。

本書では、レガシーコードを**「修正、拡張、作業が非常に難しいコード」**と定義し、レガシーコードをはじめから作らないようにするためにはどうすれば良いか、ということについて述べられています。

本書は、レガシーコードを作らないようにするためのプラクティスをただ説明するだけでなく、なぜそれが重要なのかということの説明に力点を置いてる点が非常に有用だと感じました。
特に、１章〜３章からなる「第Ⅰ部 レガシーコード危機」では、従来のソフトウェア開発プロセスがなぜレガシーコードを生み出してしまうのかということについて説明されており、普段自分自身が戦っているソフトウェア開発に関して、改めてその問題点について整理するきっかけになりました。

今回は、この第Ⅰ部の内容について、自分の頭の中を整理する目的でまとめていきたいと思います。


## １章　何かが間違っている

１章では、ソフトウェア開発におけるウォータフォール開発の問題点と、レガシーコードを生み出してしまう理由について述べられています。

> 要求 > 設計 > 実装 > 統合 > テスト > インストール > 保守

ウォーターフォール開発では、要求〜保守までの各工程に分けて開発を進め、前の工程で得られた成果物を基に次の行程の作業を行います。そのため、基本的には前の工程で後の行程で必要になる情報をすべて洗い出し、手戻りがないように進めることが前提となっています。

したがって、ウォーターフォール開発では、要求フェーズで必要になる機能をすべて洗い出し、それをもとに設計・実装を行い、それらを統合フェーズで一気に統合することになります。
多くのバグはこの統合フェーズで見つかり、それより前のフェーズでは見つかりません。それまでに作り上げられた巨大なソフトウェアを統合フェーズで一気に結合してしまうことで、問題の発見を先送りしてしまうことにつながるのです。
そして、統合フェーズ以降に発見されたバグを修正することは、多大なコストがかかる可能性があります。ソフトウェアの他の箇所にも影響が及ぶ可能性があるためです。そのため、影響がある可能性のある箇所をすべて再テストするのが望ましいですが、これが手動の場合、既に巨大なソフトウェアを作り上げてしまったため膨大なコストがかかることになってしまいます。

このように、機能をまとめて作ってリリースするのは、ソフトウェアの世界ではうまくいきません。まとめて作ることで変更に膨大なコストがかかり、結果的に変更不可能なものを作る可能性が高くなってしまうからです。

本書の著者は、機能をまとめて作るのではなく小さな単位でインクリメンタルに作って統合することで、後から修正や拡張が可能なソフトウェアを作ることができる、と述べています。これは、多くの人が共感できるのではないでしょうか。
機能をまとめて作るのは、変更不可能なものを作るリスクだけでなく、無駄なものを作ってしまうリスクも孕んでいると思います。実際、[ソフトウェアの機能のうちよく使われる機能は20％にすぎず、45％の機能は全く使われない](https://martinfowler.com/articles/xp2002.html)という調査結果もあるようです。

以上が、１章で述べられているウォーターフォール開発がレガシーコードを生み出してしまう理由です。


## ２章　CHAOSレポート再考

２章では、生み出されたレガシーコードがソフトウェア業界にどれほどの損失をもたらしているのかについて、データに基づいた分析を行なっています。

[NISTのレポート](https://www.nist.gov/system/files/documents/director/planning/report02-3.pdf)によると、ソフトウェア障害がアメリカで年間600億ドルもの損失を出しているのだそうです。

そして、[ソフトウェア開発者の80％の開発コストが「障害の特定と修正」にかけられており](http://www.abeacha.com/NIST_press_release_bugs_cost.html)、本当に価値を生み出すためのコストにはたった20％しか費やせていないのだといいます。
また、[ソフトウェアの開発にかかるコストの最大80％は、最初のリリース後のバグ修正や機能拡張のために発生する](https://dl.acm.org/doi/10.1109/MS.2001.922739)とのことです。

この原因となっているのがレガシーコードです。
保守性に価値をおかず変更のコストが高いソフトウェアを作り出してしまうことで、莫大なコストを払うことになってしまうのです。

私が働く現場でも、障害の修正に多くのコストを割いているという実感がありますし、古いレポートですがアメリカだけでもこれだけの損失を出しているというのは驚きでした。


## ３章　賢人による新しいアイデア

３章では、レガシーコードを生み出さないようにするための新しいアイデアとして、アジャイル開発の考え方やプラクティスを利用することを説明しています。

アジャイル開発では、仕事をより小さな単位に分割して進めます。その過程で、品質を保証するための余計なプロセスを排除し、開発者が集中してレガシーコードの改善に取り組めるようにすることが重要だというような趣旨のことが述べられています。

スクラムのようなアジャイル開発手法を適用するだけで、開発者が保守可能なソフトウェアを作るのに役立つようなプラクティスを採用しようとなるわけではない、と筆者は述べています。
レガシーコードを生み出さないようにするためには、スクラムのようなアジャイル開発のマネジメント手法に従いつつ、エクストリームプログラミングの技術プラクティスを、その目的を正しく理解した上で利用しなければならないとのことです。

アジャイルマニフェストに「[技術的卓越性と優れた設計に対する不断の注意が機敏さを高めます](https://agilemanifesto.org/iso/ja/principles.html)」とありますが、このアジャイルマニフェストの起案者の一人であるジェフ・サザーランド氏は「[アジャイル開発の成功の要因は技術的卓越性を求めることだ](https://www.infoq.com/news/2012/04/agile-resources-microsoft/)」と述べているのだとか。

このように、アジャイル開発を採用しつつ技術プラクティスをその目的を理解した上で利用していくことで、技術的卓越性を求めていくことがレガシーコードを生み出さないようにするための方法なのだ、ということを説いているだと理解しました。


## まとめ

「レガシーコードからの脱却」の第Ⅰ部に関して簡単にまとめてみましたが、この部分だけでも非常にためになる良書だと感じました。
第Ⅱ部ではレガシーコードからの脱却のための具体的な９つのプラクティスについて説明されています。もし機会があればこちらについてもまとめたいと思います。