制御の反転と DI の関係を完全に理解した
自分は会社で利用している web フレームワークや Angular で DI を日頃から使っているのだけれど、なんかモックとかぶちこめて便利だな、ぐらいの理解で、
制御の反転
っていう概念がよくわからなかったし、それと DI がどのようにな関係にあるかについては全然考えていなかった。なので、最近いろいろ調べてわかったことを書いてみる。
まず、制御の反転
なのだけれど、wikipediaに概念がまとめられている。しかしDI を念頭にこの文章を読んでも、この説明だとよくわからないと思う。
これはなぜかというと、この wiki に載っている例が、Dependency Injection とは直接関係ないからだ。実装技法
の項目になって、ようやく依存性の注入の話が出てくる。この時点で、依存性の注入
は制御の反転
を行うための一つの手段でしかないことがわかる。
それではいったい DI における制御の反転
は何の制御を反転しているのか?ということだけど、これは、クラスの管理(制御)の責務
を反転している。
この記事からその責務を抜粋すると、
- 依存関係の置換または更新を行う(a)
- 依存関係の有効期間の特定(b)
である。DI においては、クラスの管理(制御)の責務
を担うのは、利用する側のオブジェクトではなく、フレームワークだ。
これを Angular のユースケースで考えると、(a)は例えばユニットテストのためにモックの注入を行う場合で、 (b)はフレームワーク側の機能としてProviderや Singleton serviceを提供している点だろう。
以上を意識してから読むと面白いのが、この記事とこの記事 だ。
F#でDIするやつ / “Functional approaches to dependency injection | F# for fun and profit” https://t.co/y5xsMBtKTT
— soy-curd (@soycurd1) 2018年5月31日
React等のフロントエンドにおいて、propsは依存性の注入にあたるし、event handlingは制御の反転にあたるから、わざわざDependency Injectionの概念をJsの世界に持ち込む必要なんてないよねっていう… https://t.co/JHfxi2VRLn
— soy-curd (@soycurd1) 2018年5月30日
前者では必要な機能を持った関数を引数として渡したり、部分適用を行うことで依存性の注入を実現していて、後者では、 React は props の機能で DI 相当の機能が実現できるから、DI なんて知る必要はない、と言っている。
つまり、OOP の文脈で DI を実現するためには DI コンテナのようなフレームワークが必要だが、FP においては関数が first class であることで、言語機能として制御の反転を担保している、と言えるのかもしれない。(React は FP 側)
google の Peter Norvig のスライドで、「動的言語でのデザインパターン」というものがあって、この中で GoF のデザインパターンのうち 16 個は動的言語では不可視化されるかシンプルになると言っている。確かに Python なんかではイテレータは言語に組み込まれているし、頻出するパターンはプログラマの手を煩わせないように言語設計者が上手く取り込んでくれているのだろう。
もし FP が今後もっと台頭すれば、DI の概念もいずれは、すでに言語にビルトインされたものとして特におおげさに言及されることもなくなるのかもしれないと思った。