Magnolia Tech

いつもコードのことばかり考えている人のために。

『なぜ依存を注入するのか DIの原理・原則とパターン 』を読んで、”疎結合なアプリケーション”とは何かを考える

なんとDI(Dependency Injection)だけを扱う本の厚さが637ページ!

たぶん、もう日本で今後商業出版されることは無いであろう、DI(Dependency Injection)の解説書『なぜ依存を注入するのか DIの原理・原則とパターン 』を読みました。


はじめてDIに触れたのはGoogle Guiceだったのですが、いつの間にかオブジェクトがフィールドに生えてくる黒魔術的なテクニック、という印象でした。

”動的に実装を切り替える”、という意味ではPerlで実行時に設定に応じて実装を切り替えるモジュールをたくさん見てきたし、自分でも書いたことが有ったので、Javaなどの言語で実行時の実装選択の柔軟性を取り入れることが目的なのか、と理解していました。

しかし、この本を読むことで、DIとは保守のしやすいコードを書くためにアプリケーション全体を疎結合にするためのテクニック、ということを改めて理解することができました。

冒頭に、DIに対するよくある誤解として...

  • 依存注入は遅延バインディング(late binding)を行うときにしか用いられない。
  • 依存注入は単体(unit)テストをするときだけに関係してくる。
  • 依存注入はドーピングをしたAbstract Factoryパターンのようなものである。
  • 依存注入を導入するにはDIコンテナが必要である。

の4つが解説されています。

自分は完全にこの一つ目と四つ目の誤解にハマっていたわけです。

そもそも、本書ではDIコンテナを使わない、依存はコンストラクタ経由で渡す、という手法を徹底的に解説したのちに、プロパティベースの依存注入や、DIコンテナを使った注入の方法の解説に移る、という解説の流れを採っていて、あくまで「疎結合なコードとは何か?」を理解することを優先させる構成になっています。

ページ数は分厚いですが、冒頭の約100ページにわたって解説される「合成起点」、「コンストラクタ経由での注入」、「制御の反転(Inversion of Control)」という3つのキーワードを十分に理解できれば、この本を読む価値は十分に有ったと言えます。

後半の1/3も.NETベースのDIコンテナの解説になっているので、正直.NETでコードを書かない人にはあまり用は無いのですが、一口にDIといってもライブラリによってずいぶん思想が違うし、機能も違うんだな、ということが分かります。


一方で「実装を分離するためにコンストラクタのパラメータの一つとして実装のコードを持つオブジェクトを渡しましょう」というのは、DIという概念を知らずとも比較的自然に出てくる発想であって、あまりDIというテクニックや、DIコンテナというライブラリの豊富な機能に振り回されず、「どうしたら疎結合なコードになるか?」ということを優先して考えていくことが肝要である、ということも言えます。

どうしても概念的に高度なテクニックを使った方が「高度なコード」になると考えすぎる時期も有りますが、余計な複雑性を持ち込むより、シンプルに書き下すことがまずは大事ですよね。


ちなみに、ScalaにはAirframeというDIコンテナライブラリがあるのですが、個々の機能の必然性が今ひとつ分かっていなかったのが、この本を読むことで設計に対する理解が一段階高くなり、理解しやすくなりました。

github.com


きっと日本で今後DIだけの600ページ超えの技術書が出版されることは無いんじゃないかと思うので、.NET以外のプログラミング言語を使う人も絶対に買って読んだ方がいいですね!