達人に学ぶソフトウェアの構造と設計アスキーの鈴木さんからアンクル・ボブのクリーンアーキテクチャをもらったので、読んだ。内容にもほぼ同意できるし、良いことがたくさん書いてある。読みやすくない(正確ではない。350ページの本に対して付録などを除外しても本文34章に分割しているので、読むのはたやすい。内容が相当前後するし、依存関係が逆転している章もある。全体像を示してから細部へ進むと言えなくもないのだが、全体像を説明するための用語は細部で説明されるため、逆に全体像を理解するのが難しくなっている(とおれは感じた)ところもある。おまけが唐突に最後に来るので、なに昔話してるんだ爺さん、みたいな印象も受けることをもって、読みやすくないとここでは表現した)。本書が最も重視して、そのためにおそらく書籍の作り方にまで影響しているのは、徹底して、実装(詳細)と仕様(方針)を切り離して、後者だけにフォーカスするという方針だと思える。本気で原理原則だけを説明しきろうとしているのだ。そのために、アーキテクチャといった場合に(少なくともおれにはそう受け取れる)システムが実現すべき機能を現実のソフトェアとするために考慮すべき制約に基づいた抽象から具象へのマッピングという意味でのアーキテクチャを説明したものではない。なく、複雑なシステム全体をどう構築するかの設計指針としてのアーキテクチャについて説明したもので、徹底的に抽象化されている。したがって、現実の技術として想定されているのは少なくともオブジェクト指向プログラミングが可能なプログラミング言語であることくらいだ(それすら重要ではないかも知れない)。言いたいことはSOLIDの5文字からなる頭語で示されている。Sが単一責任の原則(コンウェイ)Oがオープン・クローズド原則(メイヤー)Lがリスコフの置換原則(リスコフ)Iがインターフェイス分離原則Dが依存関係逆転の法則(DIPと称している)2004年頃にマーティンファウラーなどとの議論で出てきた原則らしいので、目新しいものではない。その意味では、本書は2017年に上梓されたようだが、21世紀初頭のアイディアを実際のプロジェクトに適用して確信した後に書籍としてまとめたものだ。あと、ヤコブソンのユースケース、エンティティ―コントロール―バウンダリー、つまりロバストネス分析に強い影響を受けているのが特徴だ。SOLIDのうち、SOLは言うまでもないことで明々白々だから良いとして、IとDは()内に人名がないようにアンクルボブ(という名前の由来は付録に出てくる)たちの議論から生まれたもののようだ。Iは分離と訳されているが、使わないモジュールを参照するな(ビルド時に依存するモジュールは、実際に依存するモジュールのみに限定せよ)、ということに尽きる。10章で詳細が書いてあるが、例がばかげているので意味が通りにくい(全体的に、コードを可能な限り使わずに説明しようとしている(このこと自体が、詳細に依存しないアーキテクチャを説明するための方便のようにすら感じる)のだが、逆に例が誰でも理解できることを意識し過ぎたのかどうにも説得力に欠けてしまっている側面があるとおれには思える。ちなみに、Iの例は、あるモジュールXを呼び出すA、B、Cの3つのモジュールがあるときに、モジュールXのうち、Bのみが依存しているメソッドを修正して(AやCの呼出しには仮に一切影響しないとしても)Xが再ビルドされたら、AやCも再ビルドが必要になるから、XとABCの間にインターフェイスをかませるべきというものだ(makeでタイムスタンプを判断してビルドする系の言語の場合は。動的言語のほうがこの面では良いと書いてあったりする)。くだらん(単一責任だけで十分っぽい)が、Javaを使ったシステムだと無いわけではないし、再ビルドしたら変更があるはずだということになるので、そのためにはQAプロセスをAやCに対しても行う必要がでてきて......みたいなことを想定しているのかも知れない。いうわけで、Iについては変更の影響範囲を明確化するために利用しているモジュールと利用されているモジュール、利用されているモジュール内での変更可能性に応じたインターフェイスを用意するべき、ということになるのだろう。いずれにしても、実装に利用する言語などに依存した詳細のように思える。内容はくだらないという印象は変わらないのだが、次のDを実現するためには、Iがちゃんと設計できていることが大前提になるからだ。その意味でDと密接不可分の関係であり、実装時のビルドの話などとは切り離して、モジュールの依存関係を明示せよ、という原則として考える必要がある)それに対してDはえらく重要で、本書の中では繰り返し言及される。いうよりも、本書は、ほぼすべてがDの説明といっても良い。その重要性は理解できる。最初、この箇所を依存対象のオブジェクトを注入する(ようするにDI)の意味だと受け取ってあとから混乱したが、もちろん本書はそういった詳細についての本ではなく設計の本だから、意味が異なった。モジュール間の依存性を正しく整理するためには、必然的に依存関係を逆転させる必要があるという意味だ(確かにそう書いてある額面通りだったということだ)。ここでの依存には、UMLでのuse(普通の矢印。とがったほうが依存している対象のモジュール)とinherited(白抜き△の矢印。△のほうが依存している対象のクラス)の両方の意味があるのがミソとなっている。画としては当然のことを書いているのだった。