LoginSignup
1
1

More than 5 years have passed since last update.

Dependency Injectionについて調べてみた

Posted at

DIとは?

Dependencyというのは、依存性のことです。
例えば、以下の例を見てみてください。

sample.kt
class Car(val name: String) 
class User(val name: String, val car: Car)

UserクラスはCarクラスを保持しています。
つまり、UserクラスはCarクラスに依存していますね。
CarはUserの依存性です。

Injectionというのは注入のことです。
上記の例で言えば、UserクラスにCarを渡すことですね。
Userというクラスに必要としている、Carを注入しています。

依存性注入というのは、Userクラスが自分でCarを作るのではなく、外からUserにCarを渡すということです。
そうすることで、UserとCarの結びつきが薄くなります。(Carにはinterfaceを使うことでより結びつきを弱められます)
例えば、Userが他のCarオブジェクトが必要になってもUserクラスを変更する必要はありません。
Userに渡すCarオブジェクトを変更すれば良いだけです。

このおかげで、UserはCarに対する以下のような知識を減らすことができます。
1. Carの生成方法を知る必要がありません。
2. 実際にどのCarを使っているのかを知る必要がありません。(interfaceを使っているという前提で、どの具象クラスを使っているのかを知る必要がないの意)

Injectionの方法とは?

主に以下の3つの方法があります。
1. constructor
2. setter
3. interface

Dependency Injectionデザインパターンで解決したいこと

  1. 依存性オブジェクトの生成方法とクライアントコードの独立をさせたい(異なるオブジェクトが必要になった時に、クライアントコードを都度変更したくない)
  2. オブジェクトの生成方法を別ファイルで管理したい

Androidチームの現状にはどう役立つのか?

  1. テストのカバー率を上げられる?
  2. アーキテクチャにより沿った実装にできる?

1. テストのカバー率を上げられる?

Androidには、View系のほとんどのリソースを管理しているContextというオブジェクトがいます。
例えば、以下のような処理をする時に、このContextが必要になります。
1. LocalDBの操作をする
2. 画面表示系のほとんどの操作をする

みてもらえれば分かる通り、presentation層のこともやるし、data層のこともやっています。
そのため、本当にアーキテクチャに沿った実装をやろうとすると、presentation/domain/data層全てにおいてContextを参照できる必要があります。
しかし、これはテストをするには不便です。(なぜ不便なのかはわかっていない。とりあえず、Contextがいるとテストできないという認識。)
configurationファイルにオブジェクトの生成処理を書くことができるとすれば、LocalDBを参照するクラスで、Contextを持つ必要がなくなります。
なぜなら、LocalDBを外部から作成して注入することができるからです。
そうなるとdomainとdata層に関してもバッチリテストを書くことができるようになります。

2. アーキテクチャに「より」忠実な実装にできる?

現在は上で挙げた理由から、ローカルDBへの操作がViewで行われてしまっています。
ローカルDBへの操作をするためにContextが必要ではなくなれば、ローカルDBが本来あるべきであるdata層に移植できます。

そうすると、viewがentityを触ることも無くすことができるので、新しいアーキテクチャへの展望が見えてくるのだろうと思います。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1