01 / 読書ガイド
読書ガイド
引用
Winters, T., Manshreck, T., & Wright, H. (Eds.). (2020). Software Engineering at Google: Lessons Learned from Programming Over Time. O'Reilly Media. Free official edition: https://abseil.io/resources/swe-book
章の要約
第1章:ソフトウェアエンジニアリングとは何か
第 I 部「論旨」は Titus Winters によるこの一章だけで構成され、ソフトウェアエンジニアリングとは「時間で積分したプログラミング」であるという本書の主張を打ち立てる。序文で挙げられた三つのテーマ、すなわち時間と変化、規模と成長、トレードオフとコストに基づいている。ハイラムの法則(API の利用者が十分に多ければ、システムの観測可能なふるまいはすべて誰かに依存される)を紹介し、ハッシュテーブルの順序に依存したコードの例で説明して、何年も使われるコードは変化を吸収できなければならないと論じる。さらにいくつかの例(コンパイラのアップグレード、問題をより早く見つける「シフトレフト」、分散ビルド)で、組織の成長に合わせてスケールする方針としない方針を示し、最後にデータ、前例、議論に基づく意思決定を論じる。
第2章:チームでうまく働くには
第 II 部「文化」は、エンジニアリングの人間的側面を扱う Brian Fitzpatrick の章で始まる。「天才神話」や未完成の仕事を隠す習慣を批判し、早期発見やバス係数といった考え方を用いて、社会的なやり取りの三本柱(謙虚さ、尊敬、信頼)を提案する。批判の伝え方と受け止め方、責任を追及しない事後検証(ポストモーテム)の進め方について実践的な助言がある。
第3章:知識の共有
この章は学習を組織の問題として扱う。まず心理的安全性が第一であると論じ、次に知識をスケールさせる方法を説明する。質問すること、メンターシップ、グループチャット、メーリングリスト、社内の Q&A プラットフォーム、オフィスアワー、技術講演、ドキュメント、そしてコードそのものである。最後に、コードレビューを通じて行う標準化されたメンターシップである Google の readability(可読性認定)プロセスを紹介する。
第4章:公平性のためのエンジニアリング
この章は、製品開発ではバイアスが既定の状態であり、チームは多様な視点と多文化的な能力を仕事に組み込まなければならないと論じる。公に報じられた画像ラベル付けの失敗を事例として取り上げ、既存のプロセスに異を唱え、一部の利用者を傷つける製品を出すくらいなら提供を遅らせるべきだと勧める。
第5–6章:チームを率いるには、大規模なリーダーシップ
第5章は、エンジニアリングマネージャ、テックリード、その両方を兼ねるテックリードマネージャを区別し、個人の貢献者からリーダーへの移行を論じ、アンチパターン(言いなりになる人を雇う、成果の低い人を放置する、チームを子ども扱いする)と良いパターン(サーバントリーダーシップ、障害を取り除く、明確な目標を設定する、メンバーの幸福度に気を配る)を挙げる。第6章はこれを複数のチームを率いる人に広げ、三つの格言を示す。常に決定せよ(盲点とトレードオフを見極め、決めて反復する)、常に去る準備をせよ(自走するチームを作る)、常にスケールせよ(時間、注意、エネルギーを守る)である。
第7章:エンジニアリング生産性の測定
文化の部の最後の章では、Google の生産性研究チームが、ある問いがそもそも測定に値するかをまず判断し、次に「目標/シグナル/指標」(GSM)の枠組みで指標を選び、それがコードの品質、エンジニアの注意、知的な複雑さ、テンポと速度、満足度(QUANTS)を網羅しているかを確かめる方法を説明する。readability プロセスに関する一貫した例で、定性的データと定量的データを組み合わせて使う様子が示される。
第8章:スタイルガイドとルール
第 III 部「プロセス」は、Google が各言語のスタイルガイドをどのように書き、維持しているかから始まる。ルールは十分な価値を持ち、読み手のために最適化され、一貫しており、誤りやすい書き方を避けるべきである。ルールはスタイルの裁定者が関わる定められたプロセスで変更され、可能な限りエラーチェッカーや自動フォーマッタによって強制される。
第9章:コードレビュー
この章は Google のコードレビューの流れを説明する。すべての変更にはレビュアーの承認(「LGTM」)に加え、コードのオーナーの承認と、その言語の readability を持つ人の承認が必要である(後の二つは同じ人や作者自身によって暗黙に満たされることもある)。利点(正しさ、理解しやすさ、一貫性、知識の共有、履歴の記録)と、小さな変更、良い説明、少ないレビュアーといったベストプラクティスを挙げ、新規コードから大規模なリファクタリングまでのレビューの種類を区別する。
第10章:ドキュメント
ドキュメントはコードと同じように扱われる。オーナーを持ち、レビューされ、テストされ、同じワークフローに置かれる。読者を知ること、主なドキュメントの種類(リファレンス、設計ドキュメント、チュートリアル、概念的なドキュメント、ランディングページ)、ドキュメントのレビュー、そして「誰が、何を、いつ、どこで、なぜ」に答えることや古くなったドキュメントの廃止といった原則を扱う。
第11–14章:テストの概要、ユニットテスト、テストダブル、より大きなテスト
この四章が本書最大のまとまりを成す。第11章は、自動テストがなぜ変更を可能にするのかを説明し、テストを規模(小・中・大)と範囲で分類し、「ビヨンセ・ルール」(「気に入ったのなら、テストを付けておくべきだった」)を紹介し、コードカバレッジを論じ、「トイレでテスト」(Testing on the Toilet)などの取り組みで Google がテスト文化を築いた経緯を語る。第12章は保守しやすいユニットテストのための規則を示す。公開 API を通してテストする、相互作用ではなく状態をテストする、メソッドではなくふるまいをテストする、テストにロジックを書かない、テストコードは「DRY」より「DAMP」を選ぶ、などである。第13章は本物の実装、フェイク、スタブ、相互作用テストを比較し、まず本物の実装を使うよう勧め、モックの使いすぎに警告を発する。第14章はより大きなテスト(テスト対象システム、データ、操作、検証という構造と、性能テストから災害復旧までの種類)と、それが開発者の妨げにならないようにする方法を扱う。
第15章:非推奨化
プロセスの部の最後の章は、古いシステムを取り除くことは作ることより難しい場合が多いと論じ、勧告的な非推奨化と強制的な非推奨化を区別し、非推奨化の進め方を説明する。担当者、マイルストーン、ツール、そして古いシステムを動かし続ける本当のコストである。
第16–17章:バージョン管理とブランチ管理、コード検索
第 IV 部「ツール」はバージョン管理から始まる。集中型と分散型のシステム、長期間のブランチが害になる理由、トランクベース開発、Google のモノレポ、そして「ワンバージョン・ルール」である。第17章は、コードベース全体を閲覧・検索するための Google のウェブツール Code Search と、エンジニアの使い方、規模によって強いられた設計上のトレードオフを説明する。
第18章:ビルドシステムとビルドの哲学
この章は、ビルドシステムがないと何が問題になるかを説明し、タスクベースとアーティファクトベースのビルドシステムを対比し、Google の Blaze(オープンソース版は Bazel)を紹介する。ハーメティックなビルドと分散ビルド、細かい粒度のモジュール、明示的にバージョン指定された外部依存を扱う。
第19–20章:Critique(Google のコードレビューツール)、静的解析
第19章は、Google のレビューツール Critique における変更の各段階、つまり変更の作成、レビュー依頼、コメント、承認、コミットまでを順にたどり、「アテンションセット」などの機能を取り上げる。第20章は、静的解析が効果を上げる条件(誤検知が少ない、そのまま使える修正案を示す、コードレビューに組み込まれている)を説明し、Tricorder プラットフォームを紹介する。
第21–22章:依存関係の管理、大規模な変更
第21章は、依存関係の管理はソース管理より難しいと論じ、セマンティックバージョニングとその限界を検討し、安価な計算資源とテストがこの問題をどう変えうるかを考察する。第22章は数千のファイルに及ぶ大規模な変更を扱う。アトミックな変更がなぜ不可能になるのか、それを分割してテストするための基盤(Rosie というツールを含む)、そしてそれを取り込むプロセスである。
第23–25章:継続的インテグレーション、継続的デリバリー、サービスとしてのコンピュート
第23章は CI の概念と Google の TAP システムを紹介し、高速なサブミット前チェックとより遅いサブミット後のテストを区別する。第24章は継続的デリバリーの定石(機能フラグ、リリーストレイン、段階的なロールアウト、実際に使われるものだけを出荷する)を示す。第25章は、Google のクラスタ管理システム Borg がワークロードの実行をどのように標準化しているか、そして管理されたコンピュート環境向けにソフトウェアを書くには何が必要かを説明する。
あとがき
Google のエンジニアリング担当副社長による短いあとがきが、持続可能性と利用者への責任という本書のテーマを改めて述べる。
主要概念
第1章:論旨
- 時間で積分したプログラミング:ソフトウェアエンジニアリングには、コードを書くことだけでなく、その寿命全体にわたって保守し変更することが含まれる。
- ハイラムの法則:利用者が十分に多ければ、システムの観測可能なふるまいはすべて誰かが依存するものになる。
- シフトレフト:開発の流れの中で問題をより早く、修正が安く済む段階で見つけること。
第2–7章:文化
- 謙虚さ、尊敬、信頼:効果的なチームワークのために本書が提案する三本柱。
- 心理的安全性:質問したり誤りを認めたりできる環境で、知識共有の土台となる。
- Readability:コードレビューを通じて、エンジニアが言語のスタイルを身につけていることを認定する Google のメンターシッププロセス。
- 目標/シグナル/指標(GSM):チームが本当に知りたいことにさかのぼれる指標を選ぶための枠組み。
第8–10章:スタイル、レビュー、ドキュメント
- 読み手のための最適化:ルールやレビューは、速く書けるコードより後で読みやすいコードを優先する。
- LGTM とオーナーシップ:変更にはレビュアーの承認と、影響を受けるコードのオーナーの承認が必要である。
- コードとしてのドキュメント:ドキュメントをソース管理に置き、オーナーとレビューを付けて最新に保つこと。
第11–15章:テストと非推奨化
- テストの規模と範囲:使う資源(小・中・大)と、どれだけのコードを動かすかによってテストを分類する。
- DRY ではなく DAMP:テストコードは、多少の重複が生じても説明的で意味が明確であるべきだ。
- 分離より現実性を優先:スタブやモックより先に、本物の実装やフェイクを使う。
- 強制的な非推奨化と勧告的な非推奨化:利用者に古いシステムからの移行を義務づけるか、勧めるだけか。
第16–25章:ツール
- ワンバージョン・ルール:コードベースの中で、開発者が同じ依存関係の複数のバージョンから選ぶ必要が決してないようにすること。
- アーティファクトベースのビルドシステム:出力と依存関係を宣言するビルドツールで、ハーメティックかつ増分的・並列にビルドできる。
- 大規模な変更(LSC):コードベースの広範囲に及ぶためアトミックにコミットできない変更で、個別にレビュー・テストできる部分に分割される。
- サブミット前とサブミット後のテスト:変更を取り込む前には速く信頼できるテストを、後には遅いテストを実行すること。
批判的分析
長所
- 明快な統一的な考え。 エンジニアリングとは時間をかけたプログラミングであるという主張と、時間、規模、トレードオフという三つのテーマは序文と第1章で示され、各章で繰り返し現れる。そのため、スタイル、テスト、依存関係に関する方針が、規則として示されるのではなく、長く生きるコードへの影響から説明される。
- 一つの組織の経験に根ざしている。 各章はその実践を担当する Google のエンジニアが書いており、具体的な話(ハッシュ順序によるバグ、テスト文化の歴史、非推奨化の取り組み)や、ツールの満足度に関する調査結果といった社内データも含まれる。
- ツールだけでなく文化とプロセスも扱う。 エンジニアリングの本としては珍しく、チームワーク、知識共有、公平性、リーダーシップ、測定に一つの部をまるごと割き、コードレビュー、テスト、ビルドシステムと並べて論じている。
- TL;DR のまとめ。 各章は短い要点リストで終わるので、読み返しやすく、議論にも使いやすい。
短所
- Google 特有の規模とツール。 多くのツール(Critique、TAP、Borg、Rosie、Code Search)は社内のものであり、単一のモノレポやワンバージョン・ルールのような慣行は多くの組織にはない基盤に依存する。序文自身も、本書はそのまま真似るための処方箋ではないと述べている。
- 設計やプログラミングはほとんど扱わない。 序文が述べるとおり、本書はソフトウェア設計、API 設計、プロジェクト管理、セキュリティ強化、ユーザインタフェースを扱わないので、一般的なソフトウェア工学の教科書にはなりえない。
- 章ごとにばらつきのあるエッセイ風の構成。 著者が多いため章によって深さや語り口が異なり、演習、事例の設問、形式的なモデルはない。
- 2020 年時点のスナップショット。 本書は 2019–2020 年ごろの慣行とツールを記述しており、具体的なツールや組織構造など一部の細部はその後変わっている可能性がある。
コースにおける位置づけ
このソフトウェア工学の書籍リストで、Sommerville の Software Engineering は要求、設計、プロセス、検証を網羅する幅広い教科書であり、体系的な概観にはこちらが適している。Software Engineering at Google は、それと並行して、一つの大組織が保守、テスト、ツールをどう扱っているかを詳しく記したものとして読むのが効果的である。Ousterhout の A Philosophy of Software Design と Thomas と Hunt の The Pragmatic Programmer(いずれも入門)は、本書が明示的に扱わない個人レベルの設計と技能を扱うので、組み合わせるとよい。
Bass、Clements、Kazman の Software Architecture in Practice と Jackson の Software Abstractions は、それぞれアーキテクチャと形式的モデリングをより深く扱う。業界経験やインターン経験のある学生ほど Winters らの本から多くを得られる。そうした経験がない場合は、先に Sommerville か入門書を読むと背景がつかめる。
本書の使い方
本書は、現役のエンジニア、チームリーダー、そしてチームでコードを書き、バージョン管理、テスト、コードレビューを経験した上級の学生を対象としている。特定の言語は必要なく、コード例は説明のためのものである。
各章は独立しているので、選んで読むことができる。第1章は全体で使われる用語を定義するので必読である。テストに関する授業単元なら第11–14章を順に、コード品質なら第8、9、19、20章を、リリースエンジニアリングなら第16、18章と第21–24章を読むとよい。リーダーシップやチームの実践に関心のある学生は第 II 部(第2–7章)を読むこと。第25章は分散システムについてある程度の知識を前提とする。
各章の TL;DR リストを議論のきっかけとして使い、それぞれの慣行について本書自身が投げかける問い、すなわち「自分のプロジェクトの規模とコードの寿命において、このトレードオフは妥当か」を考えるとよい。無料の HTML 版は、クリエイティブ・コモンズ 表示-非営利-改変禁止ライセンスのもとで abseil.io に公開されている。
版と出典
本ガイドは、https://abseil.io/resources/swe-book で公開されている Software Engineering at Google の無料 HTML 版(初版、O'Reilly、2020 年)に基づく。推薦の序文、序文の全文、目次における部の構成、全 25 章(すべての節見出し、各章の冒頭、結論、TL;DR リスト。第1章は精読)、およびあとがきを参照している。
