前言
最近在重構項目,用到依賴注入,查了很多資料,這裏主要是記錄一下自己的理解。
正文
依賴注入的優勢:
1.代碼的可複用性
2.便於重構
3.易於測試
什麼是依賴注入?
依賴注入(DI)是一種廣泛的應用編程的技術,非常適合Android開發,通過遵循DI的原則,您可以爲良好的應用程序架構打下基礎。
類通常需要對其他類的引用, 舉個例子,Car(汽車)類可能需要對Engine(引擎)類的引用。這些必需的類稱爲依賴項,
class Car {
private Engine engine = new Engine();
public void start() {
engine.start();
}
}
class MyApp {
public static void main(String[] args) {
Car car = new Car();
car.start();
}
}
在本例中在沒有依賴注入,Car和Engine是緊密耦合的,如果現在定義一個名爲ElectricEngine的新引擎類,那麼Car類是不可複用的。
那麼依賴注入是怎麼使用的呢?與Car的每個實例在初始化時構造自己的Engine對象不同,它在構造函數中接收一個Engine對象作爲參數
class Car {
private final Engine engine;
public Car(Engine engine) {
this.engine = engine;
}
public void start() {
engine.start();
}
}
class MyApp {
public static void main(String[] args) {
Engine engine = new Engine();
Car car = new Car(engine);
car.start();
}
}
Car的可複用性。你可以把不同的引擎實現傳遞給Car。例如,您可能定義了一個名爲ElectricEngine的新引擎子類,希望Car使用它。如果您使用DI,您所需要做的就是傳遞一個更新後的ElectricEngine子類的實例,Car仍然可以工作,而不需要做任何進一步的更改。
在Android 中有兩種主要的依賴注入方式:
1.構造函數注入(上面的例子)。這就是上面描述的方法。將類的依賴項傳遞給它的構造函數。
2.字段注入(或Setter注入)。某些Android框架類(比如activity和fragments)是由系統實例化的,所以構造函數注入是不可能的。 使用字段注入,依賴項在類創建後實例化。代碼如下
class Car {
private Engine engine;
public void setEngine(Engine engine) {
this.engine = engine;
}
public void start() {
engine.start();
}
}
class MyApp {
public static void main(String[] args) {
Car car = new Car();
car.setEngine(new Engine());
car.start();
}
}
注意:依賴項注入基於控制反轉原理,其中泛型代碼控制特定代碼的執行
在前面的示例中,您自己創建、提供和管理不同類的依賴項,而不依賴於庫。這稱爲手動依賴項注入。在Car的例子中,只有一個依賴項,但是更多的依賴項和類會使依賴項的手動注入變得更加繁瑣。手動依賴注入也出現了幾個問題:
對於大型應用程序,獲取所有依賴項並正確地連接它們可能需要大量代碼。在多層體系結構中,爲了爲頂層創建對象,您必須提供它下面的所有層的依賴關係,舉個具體的例子,要造一輛真正的汽車,你可能需要一個發動機、一個變速器、一個底盤和其他部件;而發動機則需要氣缸和火花塞。那有沒有解決這個問題的方案呢?答案是:當然有了,那就是自動依賴注入。
自動依賴注入目前有兩種解決方案:
1.在運行時連接依賴項的基於反射的解決方案。
2.在編譯時生成連接依賴項的代碼的靜態解決方案。
Dagger是一個流行的Java、Kotlin和Android的依賴注入庫,由谷歌維護。Dagger通過爲您創建和管理依賴關係圖,爲您在應用程序中使用DI提供了便利。它提供了完全靜態的和編譯時的依賴關係,解決了許多基於反射的解決方案(如Guice)的開發和性能問題。
基於反射的解決方案我們這裏不講,我這裏主要是用到的Dagger,下一篇文章我會專門講解Dagger.
此外本文章如有什麼寫的不到位的地方,歡迎留言指正!!!