1. 程式人生 > >android開源庫---Dagger2學習準備(依賴注入)

android開源庫---Dagger2學習準備(依賴注入)

我這次準備介紹的是Dagger2的使用。
那麼學習這個之前我要做下準備就是了解為什麼要使用這個,那麼我們就必須要先了解一下什麼是依賴注入。

什麼是依賴注入

依賴注入控制反轉的一種實現方式。
控制反轉即IoC (Inversion of Control),它把傳統上由程式程式碼直接操控的物件的呼叫權交給容器,通過容器來實現物件元件的裝配和管理。所謂的“控制反轉”概念就是對元件物件控制權的轉移,從程式程式碼本身轉移到了外部容器。
IoC是一個很大的概念,可以用不同的方式來實現。其主要實現方式有兩種:<1>依賴查詢(Dependency Lookup):容器提供回撥介面和上下文環境給元件。EJB和Apache Avalon都使用這種方式。<2>依賴注入(Dependency Injection):元件不做定位查詢,只提供普通的Java方法讓容器去決定依賴關係。後者是時下最流行的IoC型別,其又有介面注入(Interface Injection),設值注入(Setter Injection)和構造子注入(Constructor Injection)三種方式。
這裡寫圖片描述


(我的畫圖功力有限這次我用的xmind( ⊙ o ⊙ )!)
當下比較流行控制反轉的實現方式是依賴注入,因為它是一種更可取的方式:讓容器全權負責依賴查詢,受管元件只需要暴露JavaBean的setter方法或者帶引數的構造子或者介面,使容器可以在初始化時組裝物件的依賴關係。
其與依賴查詢方式相比,主要優勢為:

  1. 查詢定位操作與應用程式碼完全無關
  2. 不依賴於容器的API,可以很容易地在任何容器以外使用應用物件
  3. 不需要特殊的介面,絕大多數物件可以做到完全不必依賴容器

(依賴查詢我就看了一下不怎麼了解就不細說了-。-)

依賴注入的基本原則

依賴注入的基本原則是:應用元件不應該負責查詢資源或者其他依賴的協作物件。配置物件的工作應該由IoC容器負責,“查詢資源”的邏輯應該從應用元件的程式碼中抽取出來,交給IoC容器負責。

我個人理解就是,在程式中,一個物件中的方法需要依賴另一個物件,該物件中儲存其所依賴物件的例項,生成依賴物件的方式不再該物件中通過new建立,而是呼叫者外部建立依賴物件,然後通過一定的方式進行傳入。

舉個例子

一個女孩依賴一個男孩

public class Girl{

    // 依賴類
    private Boy boy;

    public Girl(){
        // 在當前物件中直接 new 出依賴類
        boy = new Boy();
    }

    public void run(){
        boy.run();
    }

}
public class Boy {

    String name;

    public Boy(){

    }

    public void run(){

    }
}

此時看著無大礙,那麼如果boy發生了變化,其構造方法發生了變化,需要傳入一個姓名。比如女孩依賴叫小明的那個男孩。那還那麼需要修改程式碼:

public class Boy {

    String name;

    public Boy(String name ){
        // 修改了構造方法
        this.name = name;
    }

    public void run(){

    }
}
public class Girl{

    // 依賴類
    private Boy boy;


    public Girl(){
        //  因為Boy的構造方法發生變化,所以需要修改該處程式碼
        boy = new Boy("小明");
    }



    public void run(){
        boy.run();
    }

}

修改了Boy的構造方法之後,因為Classes依賴Boy,所以其內部也需要修改。

如果又發生了變化,比如女孩依賴的是一個叫小明的有錢的男孩(你懂的-。-)那麼又要改變Boy的構造方法。這樣的話,一個還是不明顯,當工程量很浩大時,呵呵了。(自掛東南枝)
此時,我們可以將Boy該物件的例項化交給其呼叫者,通過某種方式傳入進來。這種模式就是依賴注入。

依賴注入的三種實現方式

  1. 構造子注入(Constructor Injection)
  2. 設值注入(Setter Injection)
  3. 介面注入(Interface Injection)

上面給出過圖了這裡我就 。。。。算了還是給張圖吧
這裡寫圖片描述

1、構造方法注入(Constructor Injection)

該方式是通過構造方法將其所依賴的外部類物件傳入進來,是我認為的最簡單的方式。其實現方式如下,我們修改之前的程式碼:

public class Girl{

    // 依賴類
    private Boy boy;


    /**
     * 構造方法注入,通過構造方法傳入該物件
     * @param boy
     */
    public Girl(Boy boy) {
        this.boy = boy;
    }


    public void run() {
        boy.run();
    }

}

2、設值注入(Setter Injection)

通過手動方式呼叫set方法將Boy設定進來。

public class Girl{
    //....

    private Boy boy;

    public void setBoy(Boy boy){
        this.boy = boy;
    }

    //....

}

3、介面注入(Interface Injection)

介面方式是定義一個介面,該介面中宣告一個注入的方法,而需要注入的類實現該介面,實現介面中定義的方法。
首先,定義介面,宣告注入方法

public interface BoyInjection {

    void inject(Boy boy);
}

實現介面中的方法

public class Girlimplements BoyInjection {
    //....

    private Boy boy;


    @Override
    public void inject(Boy boy) {
        this.boy = boy;
    }

    //....

}

總結

如上的方式只不過是比較簡單的方式,真正的使用中,往往使用一些框架實現依賴注入。

Dagger2便是一個很好的依賴注入框架,我們接下來就要學習這個框架(我們做好準備接下來要開車了哈-。-)。

這裡我們認識了控制反轉和依賴注入,其實二者是一個概念。在傳統的設計過程中,通常由呼叫者來建立被呼叫的例項,控制反轉指的是建立被呼叫者的工作不再由呼叫者來完成,因此稱為控制反轉;建立被呼叫者 例項的工作通常由普通方式或者框架(Dagger2 等)來完成,然後注入呼叫者,因此也稱為依賴注入。