はじめに
Dependency injection in Androidを読んで、個人的にかなりコンパクトにまとめました。
※間違っている部分があれば指摘していただけますと幸いです。
Dependency injection(DI)とは?
クラスが必要なオブジェクトを取得するには、次の3つの方法がある
- クラス自身が必要な依存関係を構築する
- 別の場所から入手する
- パラメーターとして受け取る ⇐これがDI
DIを使わない場合(上記の1に相当)
Carクラスはコード内でEngineのインスタンスを独自に作成して初期化する
1. クラス自身が必要な依存関係を構築する
class Car {
private val engine = Engine()
fun start() {
engine.start()
}
}
fun main(args: Array) {
val car = Car()
car.start()
}
この場合の問題点
- CarとEngineが密結合している
- Carのインスタンスは1種類のEngineを使用し、サブクラスや別の実装を簡単に使用できなくなる
- テストが困難
- 別のテストケース用にEngineを変更出来なくなる
DIを使う場合(上記の3に相当)
Engineオブジェクトをコンストラクタ内でパラメーターとして受け取る
3. パラメーターとして受け取る
class Car(private val engine: Engine) {
fun start() {
engine.start()
}
}
fun main(args: Array) {
val engine = Engine()
val car = Car(engine)
car.start()
}
この場合のメリット
- 再利用性が高い
- CarにEngineの様々な実装を渡せる
- テストが容易
- 様々なシナリオでテストできる
AndroidでDIを行う主な2つの方法
コンストラクタ インジェクション
クラスの依存性をコンストラクタに渡す
Constructor Injection
class Car(private val engine: Engine) {
fun start() {
engine.start()
}
}
fun main(args: Array) {
val engine = Engine()
val car = Car(engine)
car.start()
}
フィールド インジェクション
クラスが生成された後に依存関係がインスタンス化される
Field Injection
class Car {
lateinit var engine: Engine
fun start() {
engine.start()
}
}
fun main(args: Array) {
val car = Car()
car.engine = Engine()
car.start()
}
Dependency injection(DI)のメリット
- コードの再利用性
- リファクタリングの容易さ
- テストの容易さ
参考資料
おわりに
ちなみに、AndroidでDIを行うためのライブラリは Hilt が推奨されています。
ここまで読んでいただき、ありがとうございました。
何かありましたらコメントをお願いします。