レガシーコードから脱却する

2023/01/03

プログラミング

レガシーコードとは

バグを含んでいて、難解で変更が困難なコードのこと。 テストコードの重要性から「テストのないコードはレガシーコード」ともいわれている。

レガシーコードからの脱却

レガシーコードから脱却し、ソフトウェアの開発と保守のコストを下げ、ソフトウェアの寿命を伸ばすための9つのプラクティスが紹介する。

これら9つのプラクティスは、ソフトウェア開発において非常に有効に機能するが、プラクティスの背後にある原則を理解したうえで正しく適用する必要がある。

9つのプラクティス

  • やり方より先に目的、理由、誰のためかを伝える
  • 小さなバッチで作る
  • 継続的に統合する
  • 協力しあう
  • 「CLEAN」コードを作る
  • まずテストを書く
  • テストでふるまいを明示する
  • 設計は最後に行う
  • レガシーコードをリファクタリングする
  • 1. やり方より先に目的、理由、誰のためかを伝える

    顧客やマネジャーは開発者に具体的なやり方(実装)を伝えるのではなく、目的、理由、誰のためかを伝えよう。

    ソフトウェア開発者は実装の専門家である。開発者に「目的、理由、誰のためか」を伝えることで、最終的には、機能性、保守性の面ではるかに優れた製品になるだろう。

    ストーリーを用いて「何が、なんのために、誰のために存在する」かを伝えよう。

    また、受け入れ基準を明確にして、受け入れテストを自動化しよう。

    2. 小さなバッチで作る

    大きな機能を小さなタスクに分割しよう。

    小さなタスクには「理解しやすい、見積もりしやすい、実装しやすい、テストしやすい、フィードバックが多くてリスクが少ない」などの利点がある。

    ただし、タスクは小さければよいというわけではなく、自分たちにとって正しいサイズ、すなわち計測可能な結果が見えるものにしよう。

    タスクのサイズが均一で小さければスコープボックスを、タスクに分割するのが難しければタイムボックスを使おう。

    3. 継続的に統合する

    コードを頻繁に統合することで、フィードバックサイクルを短くし、統合の際のリスクを軽減しよう。少なくとも1日に1回はコードを統合しよう。

    コードの頻繁な統合のため、ビルドを自動化、高速化しよう。

    これによって、システムはいつでもデプロイ可能な状態になる。

    4. 協力し合う

    コードの共同所有により、保守性を高めよう。

    ペアプログラミングを実施して、チーム内でコードの知識を共有しよう。

    どうしてもペアプログラミングに恐怖を感じるなら、バディプログラミングを実施しよう。

    その他の協働プラクティスとして、スパーク、スウォーム、モブも必要に応じて実施しよう。

    定期的にコードレビューとレトロスペクティブを実施しよう。

    5.「CLEAN」コードを作る

    良いコードとは「CLEAN」なコードである。

    「CLEAN」は以下に示す5つのコード品質評価尺度の頭文字をとったもの。多面的な観点からコードを評価することでコード品質を向上できる。

  • 凝集性(Cohesive)
  • 疎結合(Loosely Coupled)
  • カプセル化(Encapsulated)
  • 断定的(Assertive)
  • 非冗長(Nonredundant)
  • 「CLEAN」コードの詳細については以下を参照されたい。

    6. まずテストを書く

    テスト駆動開発を実施しよう。

    テストが負担にならないよう、必要十分な量のテストを記述しよう。テストはふるまいを表すために必要な分(1つのふるまいに対して1つのテスト)だけ記述し、コードをきれいに保とう。

    テスト駆動開発は以下のような利点がある。

  • すばやいフィードバックが得られる
  • リファクタリングする際にサポートになる
  • テスト可能なコードを書くようになる
  • 7. テストでふるまいを明示する

    テストは仕様である。テストを活用して、目的を明確に説明するようにしよう。

    あらゆる観測可能なふるまいがそれに紐づくテストを持つべきである。どのテストが失敗したかを見れば、失敗した理由がわかるようにしよう。バグはテスト不足で発生する。バグを見つけたら、バグを再現するようなテストを追加しよう。

    テストもコードである。「CLEAN」なコードを心がけよう。

    8. 設計は最後に行う

    プロジェクトの終わりごろには、システムについての理解が深まっていて、適用するデザインパターンも判断しやすい。

    設計を最後に行い、コードをリファクタリングして保守性を高めよう。設計の際は、意図によるプログラミングを行い、実装を分離してコードの抽象レベルを一定に保とう。

    テストがサポートしてくれるおかげで、安全にコードをクリーンアップできるはずだ。

    9. レガシーコードをリファクタリングする

    リファクタリングは以下の4つのコストを削減する。

  • あとからコードを理解する
  • ユニットテストの追加
  • 新しい機能の追加
  • さらにリファクタリングをする
  • レガシーコードのリファクタリングは機能レベルから始める。観測可能なふるまいに対してピニングテストを書くことから始めよう。

    次に、コードをクリーンアップして詳細を理解しよう。

    詳細がわかったら、実装を再設計しよう。

    再設計によりテストが増えていくと、より複雑なリファクタリングが可能になる。

    参考資料


    著者画像

    ゆうき

    2018/04からITエンジニアとして活動、2021/11から独立。主な使用言語はPython, TypeScript, SAS, etc.