什么是依賴注入
依賴注入(Dependency Injection),是這樣一個過程:某客戶類只依賴于服務類的一個接口,而不依賴于具體服務類,所以客戶類只定義一個注入點。在程序運行過程中,客戶類不直接實例化具體服務類實例,而是客戶類的運行上下文環境或專門組件負責實例化服務類,然后將其注入到客戶類中,保證客戶類的正常運行。
什么是控制反轉
在解釋什么是控制反轉的之前我們先引入上一篇博文一個博友在評論中提的問題:依賴注入和控制反轉不是一回事嗎?
在我看來,控制反轉這種思想最終的實現要依賴與依賴注入這種實現方式。控制反轉只是把高低層的關系發生變化,以前底層模塊在實現功能的時候可能會依賴于高層模塊,通過控制反轉可以讓底層模塊依賴于一個接口,如果這個時候高層模塊要使用底層模塊的話就必須
實現這個接口,然后通過依賴注入的方式把高層模塊的實現類注冊到底層模塊中使用。
有可能上面的解釋大家比較懵,下面我會通過舉例來進一步介紹控制反轉這種設計模式。
一個例子理解控制反轉
從上圖可以看出駕駛者依賴“汽車“和“火車”這兩個類,如果駕駛員需要開汽車話的就需要實例化一個汽車類,需要開火車的話則需要實例化一個火車類
//開汽車
汽車 cat=new 汽車();
cat.Stop();
//開火車省略。。
這個時候如果說我們需要開飛機怎么辦?傳統做法則是新建一個飛機類,然后在駕駛者直接實例化飛機類即可。
我們暫把上圖的框架成為“自動駕駛系統”,現在“自動駕駛系統”已經擁有了自動開汽車、開飛機、開火車的功能了,你覺得已經很強大了,于是把這套系統賣給了某個公司,但是這家公司的業務不僅限于前三種交通工具,現在這家公司要實現駕駛者可以駕駛飛船,如下圖所示
大家可以看到如果我們的“自動駕駛系統”要實現可以駕駛飛船的話,就需要駕駛者創建“飛船”的對象,這個時候我們的框架還是依賴于外部(因為飛船類在客戶那邊)。這個就是我們常說的底層模塊依賴于高級模塊。這種依賴肯定是不行的,隨著客戶的變化就要改動我們的框架,這種做法肯定不行,我們繼續演變。
現在我們的駕駛者并不直接依賴于某個具體實現類,而且依賴于接口,但是這個時候上圖就暴露了一個問題,希望大家先不要看下面的文字,大家可以先思考下上圖有什么問題。(上圖三個交通工具和接口的關系標識錯了,應該是實現)
上圖的設計雖然解決了不用New具體那個對象的問題,但是新的問題也隨之而來:駕駛者到底使用哪個實現類?大家都知道接口是不能直接實例化的,能夠實例化的只有接口的具體的實現類。OK,為了解決這個問題我們繼續演變
上圖我們使用工廠模式,這時候的關系是駕駛者依賴與工廠類,由工廠類具體去創建具體的實現類。根據上圖我們再看如果我們實現開飛船,那么它們之間的關系會發生什么樣的變化(上圖三個交通工具和接口的關系標識錯了,應該是實現)
通過一系列演化,現在兩者之間的關系已經徹底發生了改變,以前是底層模塊(框架)依賴于高層模塊,現在變成了高層模塊依賴于底層模塊,從上圖可以看出,無論你是要開飛船還是開火箭,只要你實現了“交通工具”接口,那么我就可以在工廠類里面給創建出來。這樣一來不僅增加了我們系統的可擴展性,也提高了我們系統的整體穩健型。
最后來總結一下到底什么是控制反轉,我的答案已經在文章開頭給出了,下面給出維基百科的答案:
控制反轉(Inversion of Control,縮寫為IoC),是面向對象編程中的一種設計原則,可以用來減低計算機代碼之間的耦合度。其中最常見的方式叫做依賴注入(Dependency Injection,簡稱DI),還有一種方式叫“依賴查找”(Dependency Lookup)。通過控制反轉,對象在被創建的時候,由一個調控系統內所有對象的外界實體,將其所依賴的對象的引用傳遞給它。也可以說,依賴被注入到對象中。
編輯:hfy
-
面向對象
+關注
關注
0文章
64瀏覽量
9994 -
控制反轉
+關注
關注
0文章
1瀏覽量
934
發布評論請先 登錄
相關推薦
評論