はじめに
依存性の注入(DI)とは?
この概念を理解することが難しかったため、現在理解しているところまで、備忘を兼ねてまとめます。
どこかの誰かの理解の助けとなれば幸いです。
依存性の注入(DI)とは?
調べた結果、最も完結な説明と感じた内容を引用します。
依存性注入とは、コンピュータプログラムのデザインパターンの一つで、オブジェクトなどの間に生じる依存関係をオブジェクト内のコードに直接記述せず、外部から何らかの形で与えるようにする手法。
この説明で最も重要なのは、「依存関係を外部から何らかの形で与える」という点です。
具体的にどう変わるか?
では、依存性の注入(DI)をすることでどのように変化するかを、下記のクラス図で確認します。
以下、依存性の注入を「DI」と略します。
DI前後で、謎のインジェクタの登場により、「UserServiceImpl(クライアント)」から「UserRepositoryImpl(サービス)」への依存が解消されていることがわかります。
このインジェクタの動作を「Dependency Injection」と呼びます。
依存性の注入(DI)前
依存性の注入(DI)後
依存性の注入(DI)の利点
これまでDIの説明をしてきましたが、DIを使うとどのような利点があるのでしょうか?
主な利点としては、下記3点です。
2.クライアントの動作がカスタマイズ可能
3.依存オブジェクトのモック化による単体テスト(ユニットテスト)が可能になる
コンポーネント間が疎結合になる
まず、クラス図で確認したように、DIすることにより、具体的な実装への参照が少なくなります。
「UserServiceImpl(クライアント)」と「UserRepositoryImpl(サービス)」の依存関係がなくなるから、それぞれのクラス名やパッケージ名が変更されても、影響がなくなるね。
クライアントの動作がカスタマイズ可能
2つ目の利点は、参照する側のクライアントの動作がカスタマイズ可能になる点です。
参照される側(クラス図でいうところのサービス)を別の実装にして、それをクライアントに渡すように変更することが可能になります。
例えば、サービスからデータベース(DB)を呼び出して保存するような場合、保存先を変更するような実装が可能になります。
依存オブジェクトのモック化による単体テスト(ユニットテスト)が可能になる
3つ目の利点は、依存オブジェクト(クラス図でいうところのサービス)をモック化することで単体テストが可能になる点です。
DI前のクラス図を再度みてみましょう。
この状態でクライアントの単体テストを実施しようとすると、サービスが返す結果が特定の状態でない(DBの情報を取ってくる、WebAPIの結果など)場合、クライアントで受け取る情報が毎回異なるため、単体テストができない状況になります。
そこで、DIをすることにより、オブジェクトの依存関係を外部から設定できるようになります。
そうすることで、サービスをモック化してクライアントに渡すことができるようになるため、単体テストが容易にできるようになります。
さいごに
依存性の注入(DI)について、理解が進みましたでしょうか?
特に大規模開発では使用することが多く、必須概念だと思います。
Scalaでの具体的な使用方法については、別途まとめようと思います。
コメント