"レガシーコード改善ガイド"読みました。

レガシーコード改善ガイド (Object Oriented SELECTION)

レガシーコード改善ガイド (Object Oriented SELECTION)

以前より多くの方にお勧め頂いていた本書を読みました。
一通り読み終えたところで、自分の言葉で各章を簡単に紹介しようと思います。

第1部 変更のメカニズム

第1章 ソフトウェアの変更

リファクタリングと最適化を交えて、ソフトウェアに変更が発生する理由とソフトウェア変更のリスクが紹介されています。

第2章 フィードバックを得ながらの作業

ユニットテストの紹介とレガシーコードを変更する際の考え方、変更手順が紹介されています。

第3章 検出と分離

クラス間の依存関係を排除する理由(検出と分離)とその方法が紹介されています。

第4章 接合モデル

プログラムの接合部について紹介されています。
接合部とは、その場所を直接編集しなくても、プログラムの振る舞いを変えることができる場所で、接合部という観点からコードを見ることでテストが容易に行えるプログラムの構造を見つけやすくなります。

第5章 ツール

レガシーコード改善を支援する「自動リファクタリングツール」や「テスティングフレームワーク」が紹介されています。

第2部 ソフトウェアの変更

第6章 時間がないのに変更しなければなりません

既存のコードをテストで保護する時間がない場合に、出来るだけ既存の振る舞いに影響を与えずに変更を実施する方法が4つ紹介されています。
「スプラウトメソッド」「スプラウトクラス」「ラップメソッド」「ラップクラス」の4つです。

第7章 いつまで経っても変更作業が終わりません

システムを変更が行い易いよくメンテナスされたシステムにするための依存関係を排除する方法を紹介しています。

第8章 どうやって機能を追加すればよいのでしょうか?

コードをテストで保護できる場合の機能を追加する方法として「テスト駆動開発」「差分プログラミング」が紹介されています。但し、「差分プログラミング」は「リスコフの置換原則(LSP)」違反するなどお勧めできる方法ではないとの記載があるので、飛ばしていい内容だと思います。

第9章 このテストをテストハーネスに入れることができません

複雑なコンストラクタしか用意されていないなど、テスト対象のクラスを簡単にインスタンス化できない場合に対処する方法が紹介されています。

第10章 このメソッドをテストハーネスで動かすことができません

「privateメソッド」や「多くのパラメータを必要とする」など、簡単にテストできないメソッドに対する対処法が紹介されています。
また、「コマンドとクエリーの分離」についても紹介されています。

第11章 変更する必要がありますが、どのメソッドをテストすればよいのでしょうか?

変更対象のメソッドのテストだけではなく、そのメソッドを使っている箇所への影響もテストする必要があるため影響スケッチを用いて影響範囲を理解することが大切だと紹介されています。

第12章 1カ所にたくさんの変更が必要ですが、関係するすべてのクラスの依存関係を排除すべきでしょうか?

依存関係を持ったままでも、いくつかの変更をまとめてテストできる場所を見つけて、上位レベルでテストを行うことには価値があり、この上位レベルのテストは将来のリファクタリングのために役立つと紹介されています。

第13章 変更する必要がありますが、どんなテストを書けばよいのかわかりません

クラスの仕様を明らかにするテストを書くべきだと紹介されています。

第14章 ライブラリへの依存で身動きが取れません

依存関係を切り離したいライブラリのクラス用に薄いラッパークラスを用意すべきと紹介されています。なお、この他の対応策の記載はありません。

第15章 私のアプリケーションはAPI呼び出しだらけです

2つの方法「APIをラップする」と「責務をもとに抽出する」が紹介されています。
「責務をもとに抽出する」のサンプルを紹介します。メール送信機能の場合「APIに依存しない送信するメールオブジェクトを作成する機能」と「APIに依存する送信する機能」とに分割することです。

第16章 変更できるほど十分に私はコードを理解していません

「メモを取る」「スケッチを描く」「印を付ける」など、コードを理解する方法が紹介されています。

第17章 私のアプリケーションには構造がありません

アプリケーションのアーキテクチャを形成、維持する方法が紹介されています。

第18章 自分のテストコードが邪魔になっています

「テストクラスの命名規則」「テストコードの配置場所」など、テストコードには規約が必要であると紹介されています。

第19章 私のプロジェクトはオブジェクト指向ではありませんが、どうすれば安全に変更できるでしょうか?

手続き型プログラム固有の依存関係を排除する手法や、オブジェクト指向拡張機能を備えた言語を使っている場合にオブジェクト指向へ移行する手法が紹介されています。

第20章 このクラスは大きすぎて、もうこれ以上大きくしたくありません

巨大なクラスの変更に立ち向かう上で一番大切な「責務を把握し、適切に分類する方法」や、変更作業の戦略/戦術が紹介されています。

第21章 同じコードをいたるところで変更しています

コードから重複を取り除く方法が紹介されています。

第22章 モンスターメソッドを変更する必要がありますが、テストを書くことができません

テストが整備されていないモンスターメソッドをリファクタリングする方法が紹介されています。

第23章 どうすれば何も壊していないことを確認できるでしょうか?

「超集中編集」や「ペアプログラミング」など、編集時のリスクを緩和するさまざまな方法が紹介されています。

第24章 もうウンザリです。何も改善できません

新規開発の芝は思っているよりも青くない。レガシーコードに取り組む上で大切なことは、その中でやりがいを感じること。との励ましが記載されています。

依存関係を排除する手法

第25章 依存関係を排除する手法

リファクタリングはテストコードが存在が前提の手法ですが、レガシーコード(テストがないコード)でも変更のリスクを緩和してリファクタリングする手法が紹介されています。

所感

本書には、レガシーコードへの取り組み方として、「リスコフの置換原則」や「依存関係逆転の原則」など技術的な内容も紹介されていますが、「超集中編集」や「ペアプログラミング」など技術的ではなく、「人間の特性」や「組織としてどう取り組んでいくべきか」という内容も紹介しており、非常に実践的だと感じました。
少し高額ですが、システムの保守を担当する方や改修を行う方にとっては価値のある1冊だと感じています。