今年の7月に第二版が出た"A Philosophy of Software Design"を読んだ。
本書では、ソフトウェアシステムの複雑性を最小化するための設計について、モジュール/クラス設計、インターフェイス設計、レイヤー設計、エラーハンドリングから、コードの書き方まで様々な側面から具体なコード例をあげつつ解説している。
ソフトウェア開発において、システムをシンプルに保ち複雑性が上がることを避ける原則は、KISS (Keep it Simple, Stupid), DRY (Do not Repeat Yourself)やYAGNI (You Ain't Gonna Need It)などが昔から言われている。これらのフレーズ自体はソフトウェアエンジニアが取るべき行動は示しているが、その理由は示していない*1。 本書では「ソフトウェアシステムの複雑性」が上がることの課題を「コードやシステムの理解が難しくなること」「コードの変更が難しくなること」の2点と定義しており、複雑性という抽象的な概念を言語化し、課題として認識しやすくしている。
昨今のソフトウェアシステムは、複数のソフトウェアエンジニアが入れかわりながら、長期間にわたって継続的に開発、運用されていくことが多く、いかに複雑性を上げずに機能を追加していくか、がシステムデザインの大きな課題となっている。 マイクロサービスもそのための方法論の一つで、一つのチームが担当する領域の境界を明確にすることで複雑性を下げることを狙った設計と言える(もちろん成功している例もあれば、失敗してかえって複雑性が増してしまっている例もある)。 いわゆる「技術的負債」も、コードの複雑性が上がり、コードの把握と修正が難しくなってしまっている状態と考えることができ、複雑性をいかに下げるべきか、という観点でリファクタリングなりを行うことができる。
本書で挙げられている具体的なポリシー、例えばコメントをどのようにどれぐらい書くべきか、例外をどのように扱うべきか、については、チームによって賛否が分かれるところもあるだろうけれども、ソフトウェアをデザインする際に複雑性を下げる(上げない)設計を良い設計ととらえる考え方は汎用性が高く、本書でカバーされていない領域(例えばマイクロサービスの設計)でも応用が効く原則だろう。
残念ながら翻訳はまだのようだけど、それほど分量も多くなく英文も平易なので、一読をお勧めしたい。
ちなみに初版と第二版の差分は、 * Chapter 21 Decide What Mattersの追加 * Chapter 6 General-Purpose Modules are Deeperの改訂 * Clean Codeと意見が分かれるところ(コメントに対する考え方)の追記 となっており、差分分のpdfが著者のサイトから確認できる。
*1:これらの原則に対して理由付けをしている文書は多数あるけれども