Android中的依賴注入

前言

最近在重構項目,用到依賴注入,查了很多資料,這裏主要是記錄一下自己的理解。

正文

依賴注入的優勢

 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.

此外本文章如有什麼寫的不到位的地方,歡迎留言指正!!!

Android開發社區
Android開發社區

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章