はじめに
数年前、自分は他部署から引き継いだ受注管理システムの改修を担当していた。中心のクラスは3000行、いちばん長いメソッドは800行。テストは一行もなく、仕様を知る手段はコードを読むことだけだった。
当時やったのは、条件分岐の隙間に自分の処理を差し込むことだった。動いた。翌月、まったく関係のない画面が壊れた。原因を追うのに三日かかった。これを何度か繰り返して、自分に足りないのはコードを書く速さではなく、壊さずに変える技術だと気づいた。
そこから読んだ本のうち、今も机の近くに置いているものを5冊選んだ。順番は扱う対象のスケール順にした。1行のコードから始まって、クラス設計、システム全体、最後にコードベースの寿命と組織まで視野が広がっていく並びだ。
言語の入門書は入れていない。文法は数週間で覚えられる。一方で設計の判断基準は、誰かの失敗を借りないまま年数だけが過ぎていく。ここに挙げたのは、その判断基準を分厚く積み上げた本ばかりだ。
① リファクタリング 既存のコードを安全に改善する(第2版) — Martin Fowler
著者のMartin FowlerはThoughtWorksのチーフサイエンティストとして数多くの現場を見てきた人物で、設計に関する議論の語彙を作ってきた側の一人だ。第2版のサンプルコードはJavaScriptになり、言語を問わず読みやすくなった。
中身は手順書に近い。「関数の抽出」「変数のインライン化」といったカタログが並び、それぞれに動機、手順、コード例が付く。名前が付いているので、レビューで「ここは関数の抽出をかけたい」と一言で伝わるようになる。
自分が一番効いたのは冒頭の長いサンプル。汚いコードを少しずつ、テストを回しながら分解していく過程が全部載っている。あの800行メソッドに手を入れる勇気は、この章から出てきた。
読み方には注意がいる。カタログ部分は通読するとかなり退屈だ。先に第1章から第4章を読み、残りは手元の困ったコードに合わせて引く辞書として扱うほうが続く。
こんな人に: テストのないコードを引き継いで、どこから触ればいいか決められない人。
② Effective Java 第3版 — Joshua Bloch
Joshua BlochはJavaのコレクションフレームワークを設計した本人だ。標準ライブラリがなぜその形になったのか、当事者の言葉で読める本は多くない。
構成は90項目の独立した助言。equalsとhashCodeの契約、ビルダーパターンの使いどころ、ジェネリクスの境界、Streamを使うべき場面と避けるべき場面。どれも「こうしろ」だけで終わらず、守らなかったときに何が起きるかまで書いてある。
Javaを書かない人にも価値がある。APIを設計する立場になったときの考え方が詰まっているからだ。引数の検証をどこでやるか、可変オブジェクトを外に漏らさないためにどうするか、この種の判断は言語をまたいで効く。
こんな人に: Javaを業務で数年書いているが、ライブラリの設計意図まで踏み込めていない人。
③ オブジェクト指向における再利用のためのデザインパターン — Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides
いわゆるGoF本。著者4人が当時の大規模なC++やSmalltalkのコードから共通構造を抜き出し、23個の型として整理した。1995年の本が今も参照され続けているのは、対象が言語機能ではなくクラス間の関係だからだ。
自分がこの本を理解したのはレビューの場だった。膨大なif-elseを書いた自分のコードを、先輩がStateパターンに書き換えてみせた。分岐が消えてクラスが増え、変更点が一箇所に集まった。あのとき初めてパターンが道具として見えた。
サンプルがC++とSmalltalkなので、読み進めるのに体力はいる。それでもDecoratorやStrategyの説明を読んでおくと、標準ライブラリの設計が急に読めるようになる。BufferedReaderのような入れ子の構造が、意図のある選択として見えてくる。
全部覚える必要はない。よく出会う5つか6つを深く理解して、残りは存在を知っておく程度で十分実務が回る。
こんな人に: 設計の話でチームと言葉が噛み合わず、共通の語彙が欲しい人。
④ システム設計の面接試験 — アレックス・シュウ
著者のアレックス・シュウはByteByteGoの運営者として知られ、システム設計の解説を図で見せることに徹している。タイトルは面接向けだが、中身は分散システムの入門として完成度が高い。
レートリミッター、URL短縮、通知システム、チャットのような題材を一つずつ取り上げ、要件の整理から容量見積もり、構成の提示、ボトルネックの検討まで一貫した流れで進む。各章に図が大量にあり、文章だけで抽象論をこねる場面がない。
自分はキャッシュ戦略と整合性の章を何度も読み返した。レプリケーション遅延をどこまで許すか、その判断を口頭で説明できるようになったのはこの本のおかげだ。設計レビューで使う言葉が増える。
日本語で読める分散システムの本として、最初の一冊に置きやすい。この本で地図を作ってから、個別のミドルウェアのドキュメントに降りていくと迷いにくい。
こんな人に: アプリは書けるが、複数台構成の設計を任されると手が止まる人。
⑤ Googleのソフトウェアエンジニアリング — Titus Winters, Tom Manshreck, Hyrum Wright
Googleで実際にコードベースを支えてきたエンジニアたちが書いた本。扱うのは数万人と数十年という規模で、ソフトウェアに何が起きるかという話だ。
軸は時間とスケールとトレードオフの三つ。依存関係のバージョンをどう上げ続けるか、テストのサイズをどう分けるか、コードレビューに何を求めるか。どれも一人のプロジェクトでは見えない問題で、組織が大きくなると必ず刺してくる。
自分の職場は数十人規模だが、テストのサイズ分類と大規模変更の章はそのまま使えた。CIが遅い原因が、単体テストのつもりで書いたDBアクセス込みのテストだったと気づけた。
600ページ超あるので通読は重い。テスト、依存関係管理、ドキュメントの章から拾い読みするのが現実的だ。
こんな人に: チームのコードベースが年々重くなっていく感覚に、対処法を探している人。
まとめ
| ステップ | 読む本 | 得られるもの |
|---|---|---|
| 既存コードに手を入れる | リファクタリング 第2版 | 壊さず変える具体的な手順 |
| コードの質を上げる | Effective Java 第3版 | API設計と落とし穴の判断基準 |
| 設計の語彙を持つ | GoFデザインパターン | クラス関係を言葉で扱う力 |
| 構成を考える | システム設計の面接試験 | 分散システムの全体地図 |
| 長期で維持する | Googleのソフトウェアエンジニアリング | 時間とスケールへの備え |
今の課題から1冊選ぶなら、こう考えている。
- レガシーコードが怖い: リファクタリング 第2版
- レビューで指摘の理由が説明できない: Effective Java 第3版
- 設計の議論が抽象論で終わる: GoFデザインパターン
- 負荷が増えたときの構成が描けない: システム設計の面接試験
- CIとビルドが年々遅くなっている: Googleのソフトウェアエンジニアリング
5冊まとめて買う必要はない。今いちばん痛いところに対応する1冊を選んで、手元のコードで試しながら読むほうが残る。