My External Storage

Dec 17, 2021 - 6 minute read - Comments - review

[書評] A Philosophy of Software Design を読んだ。複雑性を理解し、戦う術を身につけた

この記事は「おすすめ本 Advent Calendar 2021」17日目の記事となる。

今年読了した40冊ほどの本の中で一番よかった「A Philosophy of Software Design」を紹介する。

所感

本書はソフトウェアエンジニアが設計やコーディングを行なうときに何を考えるべきか教えてくれる本だ。 発売から数年経ってから読んだ私が言える立場ではないが、今までの経験の中でモヤモヤしていたりはっきりと理由が言えなかった部分を一気に言語化してくれる本だった。

「アジャイル」、「オブジェクト指向」、「DDD」などソフトウェア設計には「良い」と呼ばれるプラクティスやパターンが多く存在する。
また、「戦術的なエッセンスだけ取り入れてもよくない、戦略的なところから取りくまないといけない」なんてことを耳にすることもある。

では戦略的なプラクティスに取り組めば必ず「良い」のか?必ずしも良いわけではない。
エンタープライズFizzBuzzというリポジトリがある。皆さんご存知のFizzBuzzをプロダクトコードで使うようなパターンやアーキテクチャを適用したコードだ。

これは「悪い」。「良い」はずの戦略的アプローチをいくつか適応しているはずなのに悪い。なぜか?まず言えるのは「もうちょっと簡単に書けるよね?」ということだろう。 「覚えたデザインパターンを闇雲に適用するとよくないよ」や、「悪いほうが良い」も同様の話題だろう。

今まで「戦術的に考えるのではなく、まず戦略的なところから考える」としていたはずなのに、このような違和感に感じることがよくあった。 本書を読んでわかったのはそこに「哲学」がなかったからだった。「戦略」と「哲学」を照らし合わせ選択できていなかった。あるいはモヤモヤの正体がそのギャップにあることを言語化できず、説明することができなかった。
本書ではソフトウェアシステムを設計し作る上で一番重要な要素を「複雑さ」と定義し、一貫して複雑さと戦う術、考え方を説いている。
今まで「なんとなくよいと書いてあったからやっておこう」「”臭い”がするから止めたほうがよい」のような直感から落とし込めていない選択をすることが何回もあった。 本書を読むことで「この選択で複雑さを戦うことができるのか?」とより深く思考し伝えることができるようになった気がする。
今までの経験から選択を導けるようになり、より技術に対して深く洞察できるようになる素晴らしい本だった。もちろん紹介されているテクニックやレッドフラグ(危険の前兆)も素晴らしかった。 とくにDeep Moduleの思想とコメントの書きかたは常に意識し身につけていきたい。

どんな本なのか

https://www.amazon.co.jp/dp/B09B8LFKQL

Amazonの紹介文を引用する。

This book addresses the topic of software design: how to decompose complex software systems into modules (such as classes and methods) that can be implemented relatively independently. The book first introduces the fundamental problem in software design, which is managing complexity. It then discusses philosophical issues about how to approach the software design process and it presents a collection of design principles to apply during software design. The book also introduces a set of red flags that identify design problems. You can apply the ideas in this book to minimize the complexity of large software systems, so that you can write software more quickly and cheaply.

要約すると

本書は、ソフトウェア設計のテーマとして複雑なソフトウェアシステムをいかに分解するかということを取り上げている。 大規模なソフトウェアシステムの複雑さを最小限に抑え、より早く、より安くソフトウェアを書くための哲学、テクニックがまとめられている。

  • 「複雑性の管理方法」の紹介
  • ソフトウェア設計プロセスにどのようにアプローチするかという哲学的な問題
  • ソフトウェア設計時に適用すべき設計原則のコレクション
  • 設計上の問題を特定するためのレッドフラッグ(赤信号)の紹介

著者がGoogleで話した動画もある。

なお、本書は2021年7月に1章追加、1章修正された発売されている。
初版しか読んでいない人は新たな章が追加されているのでぜひ読んだほうが良い。
(未購入者も)初版と二版の差分を次のリンクから読むことができる。

https://web.stanford.edu/~ouster/cgi-bin/book.php

なぜ読もうと思ったのか

初版発売当初、尊敬するエンジニアのみなさんが相次いで絶賛していた。

ただ、翻訳版の出る見込みがないとのことで英語が苦手な自分は読むのを諦めていた。
しかし、技術選定やアーキテクチャを考えるような機会も増え、もっと自分の技術的判断基準の拠り所をはっきりさせたいと思うようになった。
そこでこの本に改めて挑戦し毎日10分ほど辞書サイトやKindleの単語検索を駆使しつつ少しずつ読むことにした。

読んでわかったこと

本書では終始「複雑性」の解説と戦い方が示されている。
「なんとなく悪い感じ」という自分の感覚を定性的に表現できるようになった。
なぜシンプルなインタフェースがよいのか?どうすればよいモジュールが設計できるのか?なにかの良し悪しを考えるときに「複雑さ」という判断基準を持てるようになった。
また、コメントに対する意識の持ち方は非常に参考になった。
経験上コメントに力を入れるエンジニアは総じて優秀だったので自分も本著の書き方を意識してもっとコメントを書いていこうと思った。

  • 複雑さとは、ソフトウェアシステムの構造に関するもので、システムを理解し修正することを困難にするものである。
    • 複雑かどうか?を決めるのは書き手ではなく読み手
  • 複雑さは大別して3種類ある
    • Change amplification
    • Cognitive load
    • Unknown unknowns
  • Deep Module
  • EasyとSimple
  • エラー(例外)について
  • 1回でよい設計をすることはできない
  • コメント無しでシグネチャに頼った書き方していると浅いコードになっていく
  • 実装を読まないと理解出来ないメソッドは抽象化ができていない
    • 引数のシグネチャだけじゃ表現力がたりない
  • コメントはちゃんと書くこと。
    • 「良いコードならコメントが不要」ということはない
  • どの粒度のコメントを書くのか意識する。
    • Lower-level comments add precision
    • Higher-level comments enhance intuition
    • Interface documentation
    • Cross-module design decisions
  • コメントを書くベストなタイミングは開発プロセスの最初に書くこと。コメントを書くことが設計プロセスの一部になる。
  • どうやってメンテナブルなコードを書くか
  • 一貫性
  • 明瞭性
  • 優れたソフトウェア設計のもっとも重要な要素のひとつは、重要なものとそうでないものを分けること

今後どう活かすのか

今は自分のチームでこの本の輪読会を行ない、チームで改めて複雑さや設計について議論している。
第三者と本の中身や今までの経験について話すことでより咀嚼して自分のスキルとして身につけていきたい。

また、「はじめて英語の技術書を一冊ちゃんと読んだ」という点でも大きく自信をつけることができた。
今はまた同じアプローチで少しずつ新しい英語の本を読んでいる。
元が取れそうになくて諦めていたオライリーのサブスクに登録したり、技術書以外の英語の読書もできたらなと思う。
英語アレルギー克服という意味でもこの本を今年読めたのはとてもよい経験になった。

参考

関連記事