- 1、講講什麼是依賴注入以及給我們的項目開發帶來了什麼好處
- 2、怎麼能通俗易通的了解php中的反射和依賴注入這兩個概念
- 3、依賴注入是怎麼回事
依賴注入(Dependency Injection)和控制反轉(Inversion of Control)是同一個概念。具體含義是:當某個角色(可能是一個Java實例,調用者)需要另一個角色(另一個Java實例,被調用者)的協助時,在 傳統的程序設計過程中,通常由調用者來創建被調用者的實例。但在Spring里,創建被調用者的工作不再由調用者來完成,因此稱為控制反轉;創建被調用者 實例的工作通常由Spring容器來完成,然後注入調用者,因此也稱為依賴注入。
不管是依賴注入,還是控制反轉,都說明Spring採用動態、靈活的方式來管理各種對象。對象與對象之間的具體實現互相透明。在理解依賴注入之前,看如下這個問題在各種社會形態里如何解決:一個人(Java實例,調用者)需要一把斧子(Java實例,被調用者)。
(1)原始社會裡,幾乎沒有社會分工。需要斧子的人(調用者)只能自己去磨一把斧子(被調用者)。對應的情形為:Java程序里的調用者自己創建被調用者。
(2)進入工業社會,工廠出現。斧子不再由普通人完成,而在工廠里被生產出來,此時需要斧子的人(調用者)找到工廠,購買斧子,無須關心斧子的製造過程。對應Java程序的簡單工廠的設計模式。
(3)進入“按需分配”社會,需要斧子的人不需要找到工廠,坐在家裡發出一個簡單指令:需要斧子。斧子就自然出現在他面前。對應Spring的依賴注入。
第一種情況下,Java實例的調用者創建被調用的Java實例,必然要求被調用的Java類出現在調用者的代碼里。無法實現二者之間的松耦合。
第二種情況下,調用者無須關心被調用者具體實現過程,只需要找到符合某種標準(接口)的實例,即可使用。此時調用的代碼面向接口編程,可以讓調用者和被調用者解耦,這也是工廠模式大量使用的原因。但調用者需要自己定位工廠,調用者與特定工廠耦合在一起。
第三種情況下,調用者無須自己定位工廠,程序運行到需要被調用者時,系統自動提供被調用者實例。事實上,調用者和被調用者都處於Spring的管理下,二者之間的依賴關係由Spring提供。
除非你去開發類似ZendFramework, ThinkPHP, CakePHP之類的框架,幾乎沒有機會用到這個。
這是很底層的東西,尤其是依賴注入這種東西的應用場景就是輔助開發,選型的框架支持依賴注入就行了,沒必要自己實現。而反射這個東西也差不多,在業務邏輯中我從來沒遇到過必須要靠反射解決的問題,同樣也是框架才用到。
依賴注入和控制反轉是同義詞,已合併。控制反轉(Inversion of Control,英文縮寫為IoC)是一個重要的面向對象編程的法則來削減計算機程序的耦合問題。 控制反轉還有一個名字叫做依賴注入(Dependency Injection)。簡稱DI。
起源
早在2004年,Martin Fowler就提出了“哪些方面的控制被反轉了?”這個問題。他總結出是依賴對象的獲得被反轉了。基於這個結論,他為創造了控制反轉一個更好的名字:依賴注入。許多非凡的應用(比HelloWorld.java更加優美,更加複雜)都是由兩個或是更多的類通過彼此的合作來實現業務邏輯,這使得每個對象都需要,與其合作的對象(也就是它所依賴的對象)的引用。如果這個獲取過程要靠自身實現,那麼如你所見,這將導致代碼高度耦合併且難以測試。 IoC 亦稱為 “依賴倒置原理”(“Dependency Inversion Principle”)。差不多所有框架都使用了“倒置注入(Fowler 2004)技巧,這可說是IoC原理的一項應用。SmallTalk,C++, Java 或各種.NET 語言等面向對象程序語言的程序員已使用了這些原理。 控制反轉是Spring框架的核心。 應用控制反轉,對象在被創建的時候,由一個調控系統內所有對象的外界實體,將其所依賴的對象的引用,傳遞給它。也可以說,依賴被注入到對象中。所以,控制反轉是,關於一個對象如何獲取他所依賴的對象的引用,這個責任的反轉。
編輯本段IoC是設計模式
IoC就是IoC,不是什麼技術,與GoF一樣,是一種設計模式。 Interface Driven Design接口驅動,接口驅動有很多好處,可以提供不同靈活的子類實現,增加代碼穩定和健壯性等等,但是接口一定是需要實現的,也就是如下語句遲早要執行:AInterface a = new AInterfaceImp(); 這樣一來,耦合關係就產生了,如: Class A { AInterface a; A() { } aMethod() { a = new AInterfaceImp(); } } ClassA與AInterfaceImp就是依賴關係,如果想使用AInterface的另外一個實現就需要更改代碼了。當然我們可以建立一個Factory來根據條件生成想要的AInterface的具體實現,即: InterfaceImplFactory { AInterface create(Object condition) { if(condition = condA) { return new AInterfaceImpA(); } elseif(condition = condB) { return new AInterfaceImpB(); } else { return new AInterfaceImp(); } } } 表面上是在一定程度上緩解了以上問題,但實質上這種代碼耦合併沒有改變。通過IoC模式可以徹底解決這種耦合,它把耦合從代碼中移出去,放到統一的XML 文件中,通過一個容器在需要的時候把這個依賴關係形成,即把需要的接口實現注入到需要它的類中,這可能就是“依賴注入”說法的來源了。 IOC模式,系統中通過引入實現了IOC模式的IOC容器,即可由IOC容器來管理對象的生命周期、依賴關係等,從而使得應用程序的配置和依賴性規範與實際的應用程序代碼分開。其中一個特點就是通過文本的配件文件進行應用程序組件間相互關係的配置,而不用重新修改並編譯具體的代碼。 當前比較知名的IOC容器有:Pico Container、Avalon 、Spring、JBoss、HiveMind、EJB等。 在上面的幾個IOC容器中,輕量級的有Pico Container、Avalon、Spring、HiveMind等,超重量級的有EJB,而半輕半重的有容器有JBoss,Jdon等。 可以把IoC模式看做是工廠模式的升華,可以把IoC看作是一個大工廠,只不過這個大工廠里要生成的對象都是在XML文件中給出定義的,然後利用Java 的“反射”編程,根據XML中給出的類名生成相應的對象。從實現來看,IoC是把以前在工廠方法里寫死的對象生成代碼,改變為由XML文件來定義,也就是把工廠和對象生成這兩者獨立分隔開來,目的就是提高靈活性和可維護性。 IoC中最基本的Java技術就是“反射”編程。反射又是一個生澀的名詞,通俗的說反射就是根據給出的類名(字符串)來生成對象。這種編程方式可以讓對象在生成時才決定要生成哪一種對象。反射的應用是很廣泛的,象Hibernate、Spring中都是用“反射”做為最基本的技術手段。 在過去,反射編程方式相對於正常的對象生成方式要慢10幾倍,這也許也是當時為什麼反射技術沒有普通應用開來的原因。但經SUN改良優化後,反射方式生成對象和通常對象生成方式,速度已經相差不大了(但依然有一倍以上的差距)。
編輯本段IoC的優點和缺點
IoC最大的好處是什麼?因為把對象生成放在了XML里定義,所以當我們需要換一個實現子類將會變成很簡單(一般這樣的對象都是實現於某種接口的),只要修改XML就可以了,這樣我們甚至可以實現對象的熱插撥(有點象USB接口和SCIS硬盤了)。 IoC最大的缺點是什麼?(1)生成一個對象的步驟變複雜了(其實上操作上還是挺簡單的),對於不習慣這種方式的人,會覺得有些彆扭和不直觀。(2)對象生成因為是使用反射編程,在效率上有些損耗。但相對於IoC提高的維護性和靈活性來說,這點損耗是微不足道的,除非某對象的生成對效率要求特別高。(3)缺少IDE重構操作的支持,如果在Eclipse要對類改名,那麼你還需要去XML文件裏手工去改了,這似乎是所有XML方式的缺憾所在。
編輯本段IoC實現初探
IOC關注服務(或應用程序部件)是如何定義的以及他們應該如何定位他們依賴的其它服務。通常,通過一個容器或定位框架來獲得定義和定位的分離,容器或定位框架負責: 保存可用服務的集合 提供一種方式將各種部件與它們依賴的服務綁定在一起 為應用程序代碼提供一種方式來請求已配置的對象(例如,一個所有依賴都滿足的對象), 這種方式可以確保該對象需要的所有相關的服務都可用。
編輯本段IoC 的類型
現有的框架實際上使用以下三種基本技術的框架執行服務和部件間的綁定: 類型1 (基於接口): 可服務的對象需要實現一個專門的接口,該接口提供了一個對象,可以從用這個對象查找依賴(其它服務)。早期的容器Excalibur使用這種模式。 類型2 (基於setter): 通過JavaBean的屬性(setter方法)為可服務對象指定服務。HiveMind和Spring採用這種方式。 類型3 (基於構造函數): 通過構造函數的參數為可服務對象指定服務。PicoContainer只使用這種方式。HiveMind和Spring也使用這種方式。
編輯本段IoC實現策略
IoC是一個很大的概念,可以用不同的方式實現。其主要形式有兩種: ◇依賴查找:容器提供回調接口和上下文條件給組件。EJB和Apache Avalon 都使用這種方式。這樣一來,組建就必須使用容器提供的API來查找資源和協作對象,僅有的控制反轉只體現在那些回調方法上(也就是上面所說的 類型1):容器將調用這些回調方法,從而讓應用代碼獲得相關資源。 ◇依賴注入:組件不做定位查詢,只提供普通的Java方法讓容器去決定依賴關係。容器全權負責的組建的裝配,它會把符合依賴關係的對象通過JavaBean屬性或者構造函數傳遞給需要的對象。通過JavaBean屬性注射依賴關係的做法稱為設值方法注入(Setter Injection);將依賴關係作為構造函數參數傳入的做法稱為構造子注入(Constructor Injection)
原創文章,作者:LYSOX,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/127033.html