soy-curd's blog

へぼプログラマーです [https://twitter.com/soycurd1]

制御の反転と DI の関係を完全に理解した

自分は会社で利用している web フレームワークや Angular で DI を日頃から使っているのだけれど、なんかモックとかぶちこめて便利だな、ぐらいの理解で、 制御の反転っていう概念がよくわからなかったし、それと DI がどのようにな関係にあるかについては全然考えていなかった。なので、最近いろいろ調べてわかったことを書いてみる。

まず、制御の反転なのだけれど、wikipediaに概念がまとめられている。しかしDI を念頭にこの文章を読んでも、この説明だとよくわからないと思う。

これはなぜかというと、この wiki に載っている例が、Dependency Injection とは直接関係ないからだ。実装技法 の項目になって、ようやく依存性の注入の話が出てくる。この時点で、依存性の注入制御の反転を行うための一つの手段でしかないことがわかる。

それではいったい DI における制御の反転は何の制御を反転しているのか?ということだけど、これは、クラスの管理(制御)の責務を反転している。

この記事からその責務を抜粋すると、

  • 依存関係の置換または更新を行う(a)
  • 依存関係の有効期間の特定(b)

である。DI においては、クラスの管理(制御)の責務を担うのは、利用する側のオブジェクトではなく、フレームワークだ。

これを Angular のユースケースで考えると、(a)は例えばユニットテストのためにモックの注入を行う場合で、 (b)はフレームワーク側の機能としてProviderSingleton serviceを提供している点だろう。

以上を意識してから読むと面白いのが、この記事この記事 だ。

前者では必要な機能を持った関数を引数として渡したり、部分適用を行うことで依存性の注入を実現していて、後者では、 React は props の機能で DI 相当の機能が実現できるから、DI なんて知る必要はない、と言っている。

つまり、OOP の文脈で DI を実現するためには DI コンテナのようなフレームワークが必要だが、FP においては関数が first class であることで、言語機能として制御の反転を担保している、と言えるのかもしれない。(React は FP 側)

google の Peter Norvig のスライドで、「動的言語でのデザインパターン」というものがあって、この中で GoFデザインパターンのうち 16 個は動的言語では不可視化されるかシンプルになると言っている。確かに Python なんかではイテレータは言語に組み込まれているし、頻出するパターンはプログラマの手を煩わせないように言語設計者が上手く取り込んでくれているのだろう。

もし FP が今後もっと台頭すれば、DI の概念もいずれは、すでに言語にビルトインされたものとして特におおげさに言及されることもなくなるのかもしれないと思った。