我先自己總結(jié)一下
IOC: 原來上層依賴下層,下層改變,上層也要大量的修改,不好.所以上層中拿著下層的對象,下層改變不影響上層.
DI: 上層持有下層對象,每次都要new,依賴傳遞下去,new一個(gè)上層對象,結(jié)果可能要依賴幾十個(gè)對象.太麻煩,所以spring幫我們做了控制反轉(zhuǎn),new你要的對象就行,其他的不用你管.它的實(shí)現(xiàn)就是:你要一個(gè)car,在創(chuàng)建car的時(shí)候發(fā)現(xiàn)car需要依賴框架frame,好,再創(chuàng)建一個(gè)frame,啊,創(chuàng)建frame需要底盤?行,給你創(chuàng)建個(gè)底盤,創(chuàng)建底盤時(shí)發(fā)現(xiàn)還需要輪胎,好再給你new 輪胎.new輪胎的時(shí)候,終于沒有依賴了.好,再反向的組裝起來,最后給你一個(gè)car.
好了,以下是原文
要了解控制反轉(zhuǎn)( Inversion of Control ), 我覺得有必要先了解軟件設(shè)計(jì)的一個(gè)重要思想:依賴倒置原則(Dependency Inversion Principle )。




我們現(xiàn)在換一種思路。我們先設(shè)計(jì)汽車的大概樣子,然后根據(jù)汽車的樣子來設(shè)計(jì)車身,根據(jù)車身來設(shè)計(jì)底盤,最后根據(jù)底盤來設(shè)計(jì)輪子。這時(shí)候,依賴關(guān)系就倒置過來了:輪子依賴底盤, 底盤依賴車身, 車身依賴汽車。


這就是依賴倒置原則——把原本的高層建筑依賴底層建筑“倒置”過來,變成底層建筑依賴高層建筑。高層建筑決定需要什么,底層去實(shí)現(xiàn)這樣的需求,但是高層并不用管底層是怎么實(shí)現(xiàn)的。這樣就不會出現(xiàn)前面的“牽一發(fā)動(dòng)全身”的情況。










所以我們需要進(jìn)行控制反轉(zhuǎn)(IoC),及上層控制下層,而不是下層控制著上層。我們用依賴注入(Dependency Injection)這種方式來實(shí)現(xiàn)控制反轉(zhuǎn)。所謂依賴注入,就是把底層類作為參數(shù)傳入上層類,實(shí)現(xiàn)上層類對下層類的“控制”。這里我們用構(gòu)造方法傳遞的依賴注入方式重新寫車類的定義:




這里我們是采用的構(gòu)造函數(shù)傳入的方式進(jìn)行的依賴注入。其實(shí)還有另外兩種方法:Setter傳遞和接口傳遞。這里就不多講了,核心思路都是一樣的,都是為了實(shí)現(xiàn)控制反轉(zhuǎn)。






IoC Container的第二個(gè)好處是:我們在創(chuàng)建實(shí)例的時(shí)候不需要了解其中的細(xì)節(jié)。在上面的例子中,我們自己手動(dòng)創(chuàng)建一個(gè)車instance時(shí)候,是從底層往上層new的:


而IoC Container在進(jìn)行這個(gè)工作的時(shí)候是反過來的,它先從最上層開始往下找依賴關(guān)系,到達(dá)最底層之后再往上一步一步new(有點(diǎn)像深度優(yōu)先遍歷):




實(shí)際項(xiàng)目中,有的Service Class可能是十年前寫的,有幾百個(gè)類作為它的底層。假設(shè)我們新寫的一個(gè)API需要實(shí)例化這個(gè)Service,我們總不可能回頭去搞清楚這幾百個(gè)類的構(gòu)造函數(shù)吧?IoC Container的這個(gè)特性就很完美的解決了這類問題,大大增加了項(xiàng)目的可維護(hù)性且降低了開發(fā)難度。


作者:Sevenvidia鏈接:https://www.zhihu.com/question/23277575/answer/169698662來源:知乎著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。