Dependency injectionとは?
依存性の注入とは、コンポーネント間の依存関係をプログラムから排除するため、外部の設定ファイルなどでオブジェクトを注入できるようにするソフトウェアパターンである。
Dependency injection(依存性の注入)
- 依存性は注入しない
- ソースコードから依存関係を排除するためのデザインパターン
- 依存関係は外部の設定ファイル等で、外部からオブジェクトを注入する
Dependency injectionの必要性
Class A
がInterface B
を呼び出しInterface B
の実装はClass B
が提供することを表しています
また、このようなクラス図の書き方はUMLと呼ばれる記法です。
UMLについて詳しく知りたい方は下記の書籍が網羅的に分かりやすく記載されていますのでご一読をお勧めします。
話を本題に戻します。
上記クラス図を、Javaの実装で簡易的に表すと下記のようになります
ここで改めて一つ考えてみたいと思います。なぜ
Interface B
を定義しなければならなかったのでしょうか?
Interface B
を定義する理由は、
Class A
からClass B
の実装を隠蔽するためです。
Class A
はInterface B
さえ知っていればClass B
の機能を利用でき
Interface B
さえ保守していればClass B
の変更をClass A
が受けないという状態を作りたいわけです。簡単に言えば、
Class A
とClass B
を疎結合に保っていたいのです。
なぜならClass A
でClass B
をインスタンス化している下記の実装に問題があります。
Class B
のインスタンス化をClass A
が行っているために
実装レベルではClass A
がClass B
に依存してしまっているのです。
これではInterface B
を定義した目的が損なわれてしまいます。
これに対して、Dependency injectionはClass A
からClass B
のインスタンス化を行う実装を除くことが可能となります。
Dependency injectionのメリット
Class A
とClass B
を疎結合に保つため下記の変更を加えます。
Class A
,
Class B
のインスタンス化を外部(Injector)に移譲します
-
Injector(コード上ではMain)が
Class B
をインスタンス化する -
Class A
はInterface B
のインスタンスをコンストラクタで受け取る
Class A
内は、インスタンス化するコードが排除されClass B
知らなくてよくなります。簡単に言えば
Class A
からnewを排除した訳です
Class A
がClass B
に依存しなくなることがメリットとなります
Dependency injection(依存性の注入)のメリット
- 実装視点ではインスタンス化するコードの排除
- 設計視点ではクラス間の疎結合を確保
依存関係を排除するメリット
Class A
のプログラムからClass B
への依存関係は排除されました
実際、このことにはどのようなメリットがあるか記載していきます。
インスタンスの切り替えが容易
Interface B
の実装をClass B
からClass C
に切り替える場合を想定します
Class A
には何ら変更の影響が及びません
Class A
が意識しているのは Interface B
のみでありClass B
ではありません。
Class B
の実装が仕上がるまでの間StubとしてClass C
を使うといった場合に良く用いられます
依存関係の明確化
これは設計におけるメリットです。大規模開発において依存関係の複雑化は非常に厄介な問題です。
設計方針としては切り離せるはずの2つのクラスが、大量のクラスが生み出す大量の依存関係によって実は依存しており、もはや切り離すことが不可能であるというケースは少なくありません。
各クラスが2つのクラスを参照しているだけだとしてもシステム全体で見れば大量の依存関係となります。
アーキテクチャというルールだけで管理することは非常に困難です。
Dependency injectionはプログラムから依存関係を排除します。
このため原則的にInjector以外に依存関係が発生していれば、
一律設計違反と判断できます。
つまり、Dependency injectionというシステム上の仕組みで依存関係の氾濫を防止します。
このことはアーキテクチャの維持に効果をもたらします
クリーンアーキテクチャなど依存関係の方向を限定することに重きを置いているアーキテクチャではDependency
injectionが適用されやすくなります
ライブラリ
まとめ
本記事では、Dependency injection(依存性の注入)の概念や、使う意義、メリットなどをJavaのソースコードを用いて解説しました。
いきなりDIライブラリの使用法を見ると複雑に見えて混乱しがちですが、実現したいことは非常にシンプルです。
またDependency injection以外にも様々なデザインパターンが存在します。
下記の書籍はもはやデザインパターンのバイブルともいえる昔からある書籍ですが、最近改定されDependency Injectionも盛り込まれています。
エンジニアであれば一度は読んでおくべき一冊です。
0 件のコメント :
コメントを投稿