轉自:https://github.com/android-cn...java
依賴android
若是在 Class A 中,有 Class B 的實例,則稱 Class A 對 Class B 有一個依賴。例以下面類 Human 中用到一個 Father 對象,咱們就說類 Human 對類 Father 有一個依賴。git
public class Human {github
... Father father; ... public Human() { father = new Father(); }
}
仔細看這段代碼咱們會發現存在一些問題:
(1). 若是如今要改變 father 生成方式,如須要用new Father(String name)初始化 father,須要修改 Human 代碼;
(2). 若是想測試不一樣 Father 對象對 Human 的影響很困難,由於 father 的初始化被寫死在了 Human 的構造函數中;
(3). 若是new Father()過程很是緩慢,單測時咱們但願用已經初始化好的 father 對象 Mock 掉這個過程也很困難。框架
依賴注入函數
上面將依賴在構造函數中直接初始化是一種 Hard init 方式,弊端在於兩個類不夠獨立,不方便測試。咱們還有另一種 Init 方式,以下:單元測試
public class Human {測試
... Father father; ... public Human(Father father) { this.father = father; }
}
上面代碼中,咱們將 father 對象做爲構造函數的一個參數傳入。在調用 Human 的構造方法以前外部就已經初始化好了 Father 對象。像這種非本身主動初始化依賴,而經過外部來傳入依賴的方式,咱們就稱爲依賴注入。
如今咱們發現上面 1 中存在的兩個問題都很好解決了,簡單的說依賴注入主要有兩個好處:
(1). 解耦,將依賴之間解耦。
(2). 由於已經解耦,因此方便作單元測試,尤爲是 Mock 測試。ui
Java 中的依賴注入this
依賴注入的實現有多種途徑,而在 Java 中,使用註解是最經常使用的。經過在字段的聲明前添加 @Inject 註解進行標記,來實現依賴對象的自動注入。
public class Human {
... @Inject Father father; ... public Human() { }
}
上面這段代碼看起來很神奇:只是增長了一個註解,Father 對象就能自動注入了?這個注入過程是怎麼完成的?
實質上,若是你只是寫了一個 @Inject 註解,Father 並不會被自動注入。你還須要使用一個依賴注入框架,並進行簡單的配置。如今 Java 語言中較流行的依賴注入框架有 Google Guice、Spring 等,而在 Android 上比較流行的有 RoboGuice、Dagger 等。其中 Dagger 是我如今正在項目中使用的。若是感興趣,你能夠到 Dagger 實現原理解析 瞭解更多依賴注入和 Dagger 實現原理相關信息。