前言
dagger2 是目前由Google維護(hù)的一個(gè)依賴注入的框架绰上。也是火的一塌糊涂。目前筆者也正著手學(xué)習(xí)和使用在實(shí)際項(xiàng)目中渠驼。說(shuō)到依賴注入蜈块,網(wǎng)上很多文章都是從一個(gè)小小的案例兩個(gè)類的依賴關(guān)系進(jìn)行推演,說(shuō)到依賴注入就是為了更好的解耦。但是百揭,并沒(méi)有具體講為什么要這樣解耦爽哎,筆者就想深究一下。其實(shí)也不是什么高深的東西器一,依賴注入說(shuō)到底就是寫代碼的一種套路课锌,那么為什么有這種套路呢,所謂套路其實(shí)就是大家常說(shuō)的設(shè)計(jì)模式來(lái)或者面向?qū)ο罄泊祟惖钠盹酢2恢x者讀到這里有沒(méi)有靈光一閃渺贤。
依賴倒置原則
面向?qū)ο蟮牧笤瓌t之一,英文翻譯 Dependence Inversion Principle 请毛,一種特定的解耦形式志鞍,高層模塊不依賴于低層模塊的實(shí)現(xiàn)的細(xì)節(jié),依賴模塊被顛倒了方仿,可能有點(diǎn)難理解固棚。
依賴倒置原則遵循以下幾個(gè)關(guān)鍵點(diǎn):
1 高層模塊不應(yīng)該依賴低層模塊,兩者都應(yīng)該依賴其抽象仙蚜;
2 抽象不應(yīng)該依賴細(xì)節(jié)
3 細(xì)節(jié)應(yīng)該依賴抽象此洲;
在java中,抽象就指 抽象類和接口類委粉,不能被實(shí)例化的呜师,細(xì)節(jié)就是這兩者的繼承類和實(shí)現(xiàn)類,其特點(diǎn)就是可以被實(shí)例化艳丛,就是說(shuō)可以new出來(lái)一個(gè)他的實(shí)例匣掸。高層模塊是調(diào)用端,低層模塊就是實(shí)現(xiàn)類氮双。依賴倒置在java中就是:<b>模塊之間依賴通過(guò)抽象發(fā)生碰酝,實(shí)現(xiàn)類之間不發(fā)生直接的依賴關(guān)系,其依賴關(guān)系是通過(guò)接口或抽象類產(chǎn)生的。</b>其實(shí)說(shuō)白了大白話戴差,就是面向接口編程送爸,面向抽象編程。面向接口編程是面向?qū)ο罄碚摰木柚慌汀K砸蕾嚨怪眠^(guò)程中的解耦形式袭厂,就是調(diào)用代碼中,都是用的接口類型的對(duì)象實(shí)例球匕,調(diào)用端無(wú)需知道纹磺,具體誰(shuí)實(shí)現(xiàn)的這個(gè)接口,從而實(shí)現(xiàn)解耦亮曹,在運(yùn)行和測(cè)試環(huán)境下橄杨,當(dāng)傳入不同的實(shí)現(xiàn)類可以完成不同的工作秘症。
依賴注入
通過(guò)上面的背景了解,我們知道:所謂 依賴注入 依賴就是調(diào)用端里面的接口對(duì)象式矫,或者說(shuō)這些對(duì)象就是高層調(diào)用端的依賴乡摹。如下:
下面看一小段代碼
public class Car{
private Engine engine;
public Car(){
engine = new Engine();
}
}
這段Java代碼中Car類持有了對(duì)Engine實(shí)例的引用,我們稱之為Car類對(duì)Engine類有一個(gè)依賴采转。由于沒(méi)有依賴注入聪廉,因此需要我們自己是在Car的構(gòu)造函數(shù)中創(chuàng)建Engine對(duì)象。
這樣明顯喪失了靈活性故慈,一切依賴都是在Car類的內(nèi)部創(chuàng)建板熊,Car與Engine嚴(yán)重耦合。一旦Engine創(chuàng)建方式發(fā)生了改變惯悠,我們就必須要去修改Car類的構(gòu)造函數(shù)另外我們也沒(méi)辦法替換動(dòng)態(tài)的替換依賴實(shí)例(比如我們想把Engine的品牌更換 或者更換型號(hào))邻邮。這類問(wèn)題在大型的商業(yè)項(xiàng)目中則更加嚴(yán)重竣况,往往A依賴B克婶、B依賴C、C依賴D丹泉、D依賴E情萤;一旦稍有改動(dòng)便牽一發(fā)而動(dòng)全身,想想都可怕摹恨!而依賴注入則很好的幫我們解決了這一問(wèn)題筋岛。且看下面的代碼
依賴注入其實(shí)并不神奇,我們?nèi)粘5拇a中很多都用到了依賴注入晒哄,但很少注意到它睁宰,也很少主動(dòng)使用依賴注入進(jìn)行解耦。這里我們簡(jiǎn)單介紹一下賴注入實(shí)現(xiàn)三種的方式寝凌。
1 構(gòu)造注入
public class Car{
private Engine engine;
public Car(Engine engine){
this.engine = engine;
}
}
2 接口注入 常見(jiàn)于mvp模式中
public interface Injection<T>{
void inject(T t);
}
public class Car implements Injection<Engine>{
private Engine engine;
public Car(){}
public void inject(Engine engine){
this.engine = engine;
}
}
3 set方法注入
public class Car {
private Engine engine;
public Car(){}
public void setEngine(Engine engine){
this.engine = engine;
}
}
4 注解注入
public class Car{
@Inject
Engine engine;
public Car(){}
}
這四段代碼都達(dá)到了解耦的目的柒傻,達(dá)到高內(nèi)聚低耦合的目的,保證代碼的健壯性较木、靈活性和可維護(hù)性红符。(依賴的實(shí)例化不在Car類內(nèi)部,就是不在這里new出來(lái)的)伐债,
至此预侯,所有的依賴注入功能及展示形式,是不是很簡(jiǎn)單7逅萎馅!他是如何解耦的稍微回味一下,很好理解虹蒋。今天就到這糜芳,對(duì)我自己說(shuō)晚安拣技!
文章索引
dagger2 循序漸進(jìn)學(xué)習(xí)(一)依賴注入基礎(chǔ)知識(shí)(包會(huì))
dagger2 循序漸進(jìn)學(xué)習(xí)(二)
dagger2 循序漸進(jìn)學(xué)習(xí)(三) 實(shí)例1,application中的應(yīng)用