書評『A Philosophy of Software Design』:古典的かつ本質的な設計論

ここ数日で読んだ下記の本。非常に感銘受けたので書評を書く

 

A Philosophy of Software Design

A Philosophy of Software Design

  • 作者:John Ousterhout
  • 出版社/メーカー: Yaknyam Press
  • 発売日: 2018/04/06
  • メディア: ペーパーバック
 

 

著者はスタンフォードで教えているが、元実務家らしい。大学のコースの内容を本にしたものという。研究領域は比較的低レイヤっぽい。題名は訳すと「あるソフトウェア設計の哲学」

 

総評

ソフトウェア設計を複雑性(complexity) を減じるためのものだ、という基本的な考えのもと、非常に実践的なアイデアが学生のよくある間違いや好ましい例とともに記述されている。UNIXの設計を良いものと主張する場合が多い。間違いの例などは自分もやっていたな、と思うものもあり、かなり考えさせられる。数年教えてきた内容を使っているので、伝え方がうまい。

 

基本的なアイデアは古典的なものであり、目新しいというより原点回帰の設計論。当初はビジネスアプリケーションの設計には微妙かな、と思ったが、むしろ大事と思った。

 

 

アジャイルの罪

いくつかの議論は、いわゆるあちらのアジャイルのグルたち(アンクル・ボブやケント・ベック)と違うことを主張している。例えば、Unit Testには肯定的だが、TDDは設計を疎かにする恐れあり、として否定的だ。また、「クラスは小さくすべし」というアンクル・ボブの勧めに対して、「小さく分けすぎるな」という。

 

何も考えずにアジャイルで機能中心にガンガン作るってのをやると良い設計にならない/技術的負債がたまるって認識がそろそろ一般化してきていると思われる。その対策としてDDDなんかが注目されているのだと思うけど、この本に書かれているような基本的な哲学を抜かしてそこに向かうとなかなか厳しいことになると思われる。

 

こうした短期的な機能中心のプログラミングを著者は戦術的プログラミングと呼び、より長期の良い設計を探究しながら行うプログラミングを戦略的プログラミングと呼んでいる。TDDや機能中心のアジャイルは戦術的プログラミングを助長するという。

 

私見としてはプラクティスの提唱者たちは本書における基本的な考え方を身につけているから害はないのだろう。

 

抽象化というプログラミングと設計の核心

著者はインクリメンタルな開発には賛同するけど、それは機能(feature)単位ではなく、抽象単位であるべきだという。モデル単位と言い換えてもいいと思う。

「インクリメンタルに開発する」というのは一般的にはいいアイデアだ。だが、開発の増分というのは、機能ではなく、抽象であるべきだ。もちろん、機能によって抽象が必要とされるまで考えることを延期するのはいい。だが、ひとたび、抽象が必要とされれば、適切に設計するのに時間の投資を惜しんではならない。

 

TDDが設計を阻害するメカニズムとして次のように述べている。

テスト駆動開発は過度にインクリメンタルだ。...抽象化が必要になったならば、その抽象をバラバラに作り出すことをしてはならない。抽象は全体を一度に設計しなければならない。(もしくは、ある程度核となる機能のまとまりを提供できるだけの大きさは必要だろう)

 

ある程度一般的なモジュール(somewhat general-purpose fashon)

著者がいう抽象化のための実践的な指針が「ある程度の一般化」だ。SI稼業で何らかの成功体験がある人は、顧客の要件を鵜呑みにせず、後でどうにでもなるような仕組みを提供してうまくいった経験がある人は多いだろう。これはG.M.ワインバーグが著書でも触れていたテクニックで、長い歴史がある。

 

ただ、この一般化をやりすぎると結局何ができるのかが分からなくなったり、複雑性が設定ファイルやテーブルのデータ内容に移動しただけ、ということになりかねない。SIのプロジェクトでもよく見る。なんでも入るテーブルみたいなやつもそれだろう。一般化のしすぎ。

 

著者は個別の煩雑な要件を満たし、かつ、複雑性を減じるようなバランスの取れた一般化された目的のモジュールを設計することを推奨している。著者の例はテキストエディタの編集処理の際にUIモジュールから呼ばれるメソッドだ。

 

個別のユーザーの操作に対応したメソッドを一つ一つ提供するのではなく、より一般的なメソッドを提供し、それをUIが使う。

 

個人的にはこれらの工夫はドメインモデリングにつながると感じた。ソフトウェアのUIの下の層にドメインの本質が構築される。多分、いいUIはその下の層と操作も一致するか近しくなる。

 

ソフトウェア設計の本質への回帰

本書はUNIXのファイルアクセスやネットワークプロトコルのソフトウェアとしての設計などが多く出てくる。

 

近年のDDDなんかだとともそれば、基盤的要素は軽視されがちだけど、ソフトウェアを作る上ではそれらも大切な要素の一つ。むしろ、技術的な要素は上手く設計がされている場合が多いから問題にならない、といった方がいいかもしれない。TCPを意識することが我々があまりないってのは偉大な設計の勝利なんだよな。

 

この本は現代のプログラマが、ソフトウェア設計の歴史的な蓄積を身につけるのに非常に優れた本だと思う。そしてそれは新しいテクニックをみにつけ、活用するための土台になる。

 

こういうのが大学で教えられている、というのは非常に素晴らしいことだな、と思った。