Dagger2 簡單入門三部曲(一)——是什麼?
Dagger2 簡單入門三部曲(一)——是什麼?
Dagger2 簡單入門三部曲(二)——為什麼使用?
Dagger2 簡單入門三部曲(三)——怎麼使用?(進行中)
Github 的介紹是:A fast dependency injector for Android and Java。(Android和Java的快速依賴注入器)
通過上邊瞭解到依賴注入這個詞
,在Android
和Java
中什麼是依賴注入
呢?
依賴注入是什麼?
在軟體工程領域,依賴注入(Dependency Injection)是用於實現控制反轉(Inversion of Control)的最常見的方式之一。
上面提到控制反轉
這個詞,那麼什麼是控制反轉
呢?
控制反轉是什麼?
百度百科 是這麼介紹的:
控制反轉(
Inversion of Control
,縮寫為IoC
),是物件導向程式設計中的一種設計原則,可以用來減低計算機程式碼之間的耦合度。其中最常見的方式叫做依賴注入(Dependency Injection
,簡稱DI
),還有一種方式叫“依賴查詢”(Dependency Lookup
)。通過控制反轉,物件在被建立的時候,由一個調控系統內所有物件的外界實體,將其所依賴的物件的引用傳遞給它。也可以說,依賴被注入到物件中。
民間通俗理解:
就是你一個類裡面需要用到很多個成員變數,傳統的寫法,你要用這些成員變數,那麼你就
new
出來用唄~~IoC
的原則是:NO
,我們不要new
,這樣耦合度太高;你配置個xml
檔案,裡面標明哪個類,裡面用了哪些成員變數,等待載入這個類的時候,我幫你注入(new
)進去;
這裡又有個問題,解耦解的誰和誰的耦?
下面來看實現一個導演名來搜尋電影的程式碼:
public class MovieLister {
private MovieFinder finder;
public MovieLister() {
// MovieFinderImpl 實現裡具體的查詢所有電影方法
finder = new MovieFinderImpl();
}
/**
* 根據導演名來搜尋電影,返回電影集合
* @param arg 導演名
*/
public Movie[] moviesDirectedBy(String arg) {
// 獲取所有電影
List allMovies = finder.findAll();
for (Iterator it = allMovies.iterator(); it.hasNext();) {
Movie movie = (Movie) it.next();
// 移除不是該導演的電影
if (!movie.getDirector().equals(arg)) it.remove();
}
return (Movie[]) allMovies.toArray(new Movie[allMovies.size()]);
}
...
}
/**
* 抽象實現介面
*/
public interface MovieFinder {
List findAll();
}
以上程式碼看起來還是很美觀的,但是
當我們希望修改 finder
,將finder
替換為一種新的實現時(比如為MovieFinder
增加一個參數列明Movie
資料的來源是哪個資料庫),我們不僅需要修改MovieFinderImpl
類,還需要修改我們MovieLister
中建立MovieFinderImpl
的程式碼
這就是依賴注入要處理的耦合。這種在MovieLister
中建立MovieFinderImpl
的方式,使得MovieLister
不僅僅依賴於MovieFinder
這個介面,它還依賴於MovieListImpl
這個實現。 這種在一個類中直接建立另一個類的物件的程式碼, 是一種導致耦合的方式。
那麼我們如何去實現依賴注入從而達到解耦呢?
常用的有三種方式實現
- 建構函式 注入(Contructor Injection)
繼續拿上面的程式碼來分析,通過建構函式注入可以讓MovieLister
就只依賴於我們定義的MovieFinder
介面,而不依賴於MovieFinder
的實現了,這就減少了一個耦合。實現的程式碼如下:
public class MovieLister {
private MovieFinder finder;
public MovieLister(MovieFinder finder) {
this.finder = finder;
}
...
}
- setter 注入
下面的實現也是減去了MovieFinderImpl
的耦合
public class MovieLister {
private MovieFinder finder;
...
public void setFinder(MovieFinder finder) {
this.finder = finder;
}
}
- 介面 注入
首先要建立一個注入使用的介面:
public interface InjectFinder {
void injectFinder(MovieFinder finder);
}
之後,我們讓MovieLister
實現這個介面
class MovieLister implements InjectFinder {
private MovieFinder finder;
...
public void injectFinder(MovieFinder finder) {
this.finder = finder;
}
...
}
這裡貼出利用介面注入實現解耦後的完整程式碼:
// MovieFinder
public interface MovieFinder {
List findAll();
}
// MovieFinderImpl 具體實現
public class MovieFinderImpl implements MovieFinder {
private static final String TAG = "MovieFinderImpl";
@Override
public List findAll() {
Log.e(TAG, "findAll: 查詢所有電影");
return new ArrayList();
}
}
先定義一個介面
public interface InjectFinder {
void injectFinder(MovieFinder finder);
}
實現該介面
public class MovieLister implements InjectFinder{
private static final String TAG = "MovieLister";
private MovieFinder finder;
/**
* 根據導演名來搜尋電影,返回電影集合
* @param arg 導演名
*/
public Movie[] moviesDirectedBy(String arg) {
// 獲取所有電影
List allMovies = finder.findAll();
// 簡單列印語句
Log.e(TAG, "moviesDirectedBy: 移除不是"+arg+"導演的電影" );
return (Movie[]) allMovies.toArray(new Movie[allMovies.size()]);
}
@Override
public void injectFinder(MovieFinder finder) {
this.finder = finder;
}
}
呼叫:
MovieFinder movieFinder = new MovieFinderImpl();
MovieLister movieLister = new MovieLister();
// 這裡通過介面注入
movieLister.injectFinder(movieFinder);
movieLister.moviesDirectedBy("張藝謀");
不出意外,執行之後會得到如下的顯示結果:
綜上所述
Dagger2
是一個依賴注入框架,用於實現控制反轉的一種方式,主要是為了降低程式碼之間的耦合度。常見的依賴注入解耦方式有:建構函式注入、setter 注入、介面注入。
控制反轉的實現還有另一種方式是
依賴查詢
,這裡暫時不深入研究了。
文章到這裡就結束了,下篇文章介紹,為什麼使用 Dagger2。
相關文章
- Docker入門為什麼可以這麼簡單?Docker
- gRPC(一)入門:什麼是RPC?RPC
- Docker 入門:什麼是 Docker ?Docker
- 簡單理解什麼是MapReduce!
- webgl入門(1)-什麼是webglWeb
- MyCat入門篇-什麼是MyCat
- Dagger2入門使用
- Dagger2從入門到補胎(一)
- AV Foundation簡單入門之一
- SpringDataJPA入門就這麼簡單Spring
- SpringMVC入門就這麼簡單SpringMVC
- IronPython入門:什麼是IronPython?Python
- 是什麼JSON,簡單介紹JSON
- 災備是什麼意思?怎麼簡單理解?
- Spring Security極簡入門三部曲(上篇)Spring
- Spring Security極簡入門三部曲(中篇)Spring
- Spring Security極簡入門三部曲(下篇)Spring
- Azkaban 簡單入門
- postgresql 簡單入門SQL
- SprintBoot簡單入門boot
- Vue簡單入門Vue
- Kafka簡單入門Kafka
- Mysql 簡單入門MySql
- git簡單入門Git
- Espresso 簡單入門Espresso
- Groovy 簡單入門
- springmvc簡單學習(一)-----入門SpringMVC
- 超級簡單的sql入門(一)SQL
- 機器學習最好的入門課程是什麼?機器學習
- 簡單認識什麼是UI設計UI
- 什麼是單點登入?如何實現?
- 這可能是最簡單易懂的機器學習入門機器學習
- sql簡單入門的一些操作SQL
- libev教程一:libev簡單入門
- 策劃入門(一)什麼樣的創意是可行的(轉)
- 小程式 – 簡單入門
- PWA超簡單入門
- SpringSecurity簡單入門SpringGse