『レガシーコードからの脱却 ―ソフトウェアの寿命を延ばし価値を高める9つのプラクティス』を読んで


はじめに

『レガシーコードからの脱却 ―ソフトウェアの寿命を延ばし価値を高める9つのプラクティス』という本を飛んだのでアウトプットします。以降記事内では『レガシーコードからの脱却』や『本書』と省略します。

どんな本か

内容や目次は↓に記載されています。 www.oreilly.co.jp

なぜ読むのか

『プリンシプル オブ プログラミング』を読んだ理由と近いのですが、より良いコードを書くためには、そしてより良いソフトウェアを作るためにはどうすればいいかを学びたかったからです。また、読み始めた当時は所謂"レガシーコード"に苦しんでいるチームで働いていたので、タイトルに惹かれました。単純に評判が良く、ITエンジニア本大賞2020にも選ばれているのも決め手の1つになりました。

www.shoeisha.co.jp


ざっくり感想

タイトルが『レガシーコードからの脱却』になっているので、既にあるレガシーコードをどうしていくかの話が書いてありそうに思えますが、レガシーコードを作らないためにどうしていくかがメインで書かれています。

基本的にはアジャイルの考え方が推されており、レガシーコードやこれまでの開発方法を改善していこうという話と、良いソフトウェアを開発するための9つのプラクティスが紹介されています。著者のソフトウェア開発や業界をよくしていこうという熱い思いが伝わってきて、プラクティスを実践する気にさせてくれました。但し紹介されている内容は開発の進め方に関する紹介が多く、1人のエンジニアが「やりましょう!」といってもチームに導入するのはなかなか難しいと思います。全部がそうではなく意識すれば1人で実践できることも書かれています。

ソフトウェア開発未経験者が読もうと思うような類の本ではないとは思いますが、ソフトウェア開発のプロジェクトに関わった経験や、進め方をある程度理解していないと、読んでもピンとこないことも多いかもしれないので注意が必要です。開発経験のある人、特にチームをマネジメントやリードしていくポジションの人には是非知っておいていただきたい内容が詰まっている本だと思います。

翻訳者の吉羽龍太郎さんが本書についてAWS DevDayで発表した時の資料を公開してますので、読むかどうか迷っている人は一度目を通してみると参考になると思います。

www.ryuzee.com


"レガシーコード"の定義

訳者まえがきから引用

修正や拡張、作業が難しいコード

裏表紙から引用

バグを多く含み、壊れやすく拡張が難しいコード

翻訳者の吉羽龍太郎さんの資料から引用

理由は問わず修正、拡張、作業が難しいコード


原則とプラクティス

原則

  • 目指すべき姿で、価値のあるゴール
  • 簡潔で明確に定義されてなければいけない
  • 何をやるべきかを教えてくれる


ラクティス

  • 原則を実現する方法
  • 3つの条件を満たす
    • ほとんどの場合に価値がある
    • 学ぶのが容易、教えるのが容易
    • 考えなくてもやれるぐらいシンプル


4.6 原則がプラクティスをガイドする に書いてある投資での例

原則 = 「安く買って、高く売れ」
ラクティス = ドルコスト平均法


9つのプラクティス

「詳細は本を読んでね」となりますが、自分用に簡単にまとめておきます。


1. やり方より先に目的、理由、誰のためかを伝える

マネージャーやプロダクトオーナーは、開発者に「やり方」ではなく「目的、理由、誰のためか」を伝えるべきという考え方です。「やり方」を伝えると開発者は「やり方」に縛られてしまい、良い実装になりにくくなるので、開発者に「やり方」は任せようということです。

5.8 本章のふりかえり から一部引用

これによって実装の詳細は隠れ、コードはよりシンプルで、拡張するためのコストも低いものになる。ストーリーが要求に代わり、開発が発見になれば、事前に洗い出そうとしていたときよりもより良いプロダクトを作れるのだ。


2. 小さなバッチで作る

タスクを小さく(短い時間で終わるように)しようという考え方です。タスクを小さくすることで以下のようなメリットがあります。

  • 理解しやすい
  • 見積もりがしやすい
  • 実装しやすい
  • テストがしやすい
  • より多くのフィードバックの機会があるのでリスクが少ない


3. 継続的に統合する

実装したものをビルドしながら常に(実装する度に)統合しようという考え方です。これを継続的インテグレーションと呼びます。常に統合することで問題を早期発見できます。継続的インテグレーションは実装する度に統合してデプロイしなければいけないということではなく、デプロイ可能な状態にしておくことです。


4. 協力しあう

一番価値のあるリソースは一緒に働くメンバーであり、 知識をグループに広げるために協働しようという考え方です。この章では協働を最大化するのに役立つ方法として以下のような方法が紹介されています。これらについては他の資料や実践を通してより深く学んでいきたいところ。

『8.9 常にメンター、メンティー』であれに書かれているスコット・ベインさんの言葉「常に誰かのメンターであれ、常に誰かのメンティーであれ」は改めて心がけていきたい。


5. 「CLEAN」コードを作る

良いコード =「CLEAN」コードを書こうという考え方です。「CLEAN」は以下の頭文字です。

  • Cohesive (凝縮性)
    • 凝縮性のあるコードは副作用を減らす
    • 単一の責任を持つべし
  • Loosely Coupled (疎結合)
    • 疎結合なコードはテストが容易である
    • 疎結合なコードは利用しているコードに対して間接的にしか依存しない
  • Encapsulanted (カプセル化)
    • カプセル化されたコードは簡単に拡張できる
    • 実装の詳細を外部の世界からは見えない状態にすべし
  • Assertive (断定的)
    • 断定的なコードはソフトウェアがモジュール化される
    • 絶えず他のオブジェクトを参照している = 断定的ではない
  • Nonredundant (非冗長)
    • 非冗長なコードは保守の問題を減らす
    • 同じことを繰り返さないこと

『9.8.2 保守しやすいコードを書く7つの戦略』にはいいこと書いてある。というメモだけ残しておく。


6. まずテストを書く

最初にテストを書き、次にテストに合格するのに必要なコードだけを書こうという考え方です。所謂テスト駆動開発テストファースト開発です。安全なリファクタリングや仕様の理解に役立ちます。ここは自分が全くやったことないので、書いてあることはわかるがイメージできてないという状態です。


7. テストでふるまいを明示する

生きた仕様を作るために、テストにふるまいを記述しようという考え方です。1つ前の『6. まずテストを書く』と結構似ています。JUnitを使った実際のテストコードの例が書かれています。


8. 設計は最後に行う

章のタイトルと、自分の中での"設計"という言葉の理解がイマイチ噛み合ってないのですが、章の最初に「ソフトウェアの保守性を設計するのに最適なタイミングがコードとテストが書かれた後である」ということが書かれおり、そういう考え方ならなんとなくわかるな、と思った章です(?)。要するに保守性の高い作りにしていこう、そのために継続的に改善していこうという話だと理解しています。また、開発の中で学んだことを設計に反映していこうということも書かれています。


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

これは章のタイトルそのままの考え方です。リファクタリングとは、外部へのふるまいを変更せずにコードを変えることです。リファクタリングは、既存のコードを学ぶための良い方法であるとも書かれています。「コードを読む回数は、コードを書く回数の10倍以上だ」が印象的でした。