我先自己總結(jié)一下
IOC: 原來上層依賴下層,下層改變,上層也要大量的修改,不好.所以上層中拿著下層的對象,下層改變不影響上層.
DI: 上層持有下層對象,每次都要new,依賴傳遞下去,new一個上層對象,結(jié)果可能要依賴幾十個對象.太麻煩,所以spring幫我們做了控制反轉(zhuǎn),new你要的對象就行,其他的不用你管.它的實(shí)現(xiàn)就是:你要一個car,在創(chuàng)建car的時候發(fā)現(xiàn)car需要依賴框架frame,好,再創(chuàng)建一個frame,啊,創(chuàng)建frame需要底盤?行,給你創(chuàng)建個底盤,創(chuàng)建底盤時發(fā)現(xiàn)還需要輪胎,好再給你new 輪胎.new輪胎的時候,終于沒有依賴了.好,再反向的組裝起來,最后給你一個car.
好了,以下是原文
要了解控制反轉(zhuǎn)( Inversion of Control ), 我覺得有必要先了解軟件設(shè)計(jì)的一個重要思想:依賴倒置原則(Dependency Inversion Principle )。
我們現(xiàn)在換一種思路阁最。我們先設(shè)計(jì)汽車的大概樣子,然后根據(jù)汽車的樣子來設(shè)計(jì)車身骇两,根據(jù)車身來設(shè)計(jì)底盤速种,最后根據(jù)底盤來設(shè)計(jì)輪子。這時候低千,依賴關(guān)系就倒置過來了:輪子依賴底盤配阵, 底盤依賴車身馏颂, 車身依賴汽車。
這就是依賴倒置原則——把原本的高層建筑依賴底層建筑“倒置”過來麸拄,變成底層建筑依賴高層建筑派昧。高層建筑決定需要什么,底層去實(shí)現(xiàn)這樣的需求拢切,但是高層并不用管底層是怎么實(shí)現(xiàn)的蒂萎。這樣就不會出現(xiàn)前面的“牽一發(fā)動全身”的情況。
所以我們需要進(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的第二個好處是:我們在創(chuàng)建實(shí)例的時候不需要了解其中的細(xì)節(jié)哎榴。在上面的例子中,我們自己手動創(chuàng)建一個車instance時候僵蛛,是從底層往上層new的:
而IoC Container在進(jìn)行這個工作的時候是反過來的飘言,它先從最上層開始往下找依賴關(guān)系,到達(dá)最底層之后再往上一步一步new(有點(diǎn)像深度優(yōu)先遍歷):
實(shí)際項(xiàng)目中,有的Service Class可能是十年前寫的笋熬,有幾百個類作為它的底層热某。假設(shè)我們新寫的一個API需要實(shí)例化這個Service,我們總不可能回頭去搞清楚這幾百個類的構(gòu)造函數(shù)吧胳螟?IoC Container的這個特性就很完美的解決了這類問題昔馋,大大增加了項(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)載請注明出處。