javascript
Spring---浅谈IOC
概念
IOC(Inversion of Control 控制反轉)是spring的核心,貫穿始終。所謂IOC,對于spring框架來說,就是由spring來負責控制對象的生命周期和對象間的關系。
傳統開發模式與IOC開發模式的對比
傳統開發模式:對象之間互相依賴。在一個對象中,如果要使用一個另外的對象,就必須要得到它,就必須要new一個,使用完之后,我們還要將對象銷毀,比如說數據庫的連接。對象始終會對其它的接口或類耦合起來。
IOC開發模式:IOC容器安排對象之間的依賴。所有的類都會在Spring容器當中登記,告訴Spring你是一個什么東西,你需要什么東西,然后Spring會在系統運行到適當的時候把你所要的東西主動送給你,同時也把你交給其它需要你的東西,所有的類的創建銷毀都由Spring來控制,也就是說控制對象生存周期的不再是引用它的對象,而是Spring。對于某個對象具體而言,以前是它控制其它對象,而現在是所有的對象都由Spring控制,所以這叫控制反轉。
IOC的理論背景
圖一:耦合的對象
上圖一是我們傳統系統當中,對象之間相互引用的一幅圖形。我們都知道,在采用面向對象方法設計的軟件系統中,它的底層實現都是由N個對象組成的,所有的對象通過彼此的合作,最終實現系統的業務邏輯。如果我們打開機械式手表的后蓋,就會看到與上面類似的情形,各個齒輪分別帶動時針、分針和秒針順時針旋轉,從而在表盤上產生正確的時間。圖1中描述的就是這樣的一個齒輪組,它擁有多個獨立的齒輪,這些齒輪相互嚙合在一起,協同工作,共同完成某項任務。我們可以看到,在這樣的齒輪組中,如果有一個齒輪出了問題,就可能會影響到整個齒輪組的正常運轉。齒輪組中齒輪之間的嚙合關系,與軟件系統中對象之間的耦合關系非常相似。對象之間的耦合關系是無法避免的,也是必要的,這是協同工作的基礎。現在,伴隨著工業級應用的規模越來越龐大,對象之間的依賴關系也越來越復雜,經常會出現對象之間的多重依賴性關系,因此,架構師和設計師對于系統的分析和設計,將面臨更大的挑戰。對象之間耦合度過高的系統,必然會出現牽一發而動全身的情形。
如何降低系統之間、模塊之間和對象之間的耦合度,是軟件工程永遠追求的目標之一。為了解決對象之間的耦合度過高的問題,軟件專家Michael Mattson提出了IOC理論,用來實現對象之間的“解耦”,目前這個理論已經被成功地應用到實踐當中,很多的J2EE項目均采用了IOC框架產品。
圖二:解耦的過程
上圖二就是利用IOC的原理為對象之間的關系進行解耦。簡單來說就是把復雜系統分解成相互合作的對象,這些對象類通過封裝以后,內部實現對外部是透明的,從而降低了解決問題的復雜度,而且可以靈活地被重用和擴展。IOC理論提出的觀點大體是這樣的:借助于“第三方”實現具有依賴關系的對象之間的解耦。
大家看到了吧,由于引進了中間位置的“第三方”,也就是IOC容器,使得A、B、C、D這4個對象沒有了耦合關系,齒輪之間的傳動全部依靠“第三方”了,全部對象的控制權全部上繳給“第三方”IOC容器,所以,IOC容器成了整個系統的關鍵核心,它起到了一種類似“粘合劑”的作用,把系統中的所有對象粘合在一起發揮作用,如果沒有這個“粘合劑”,對象與對象之間會彼此失去聯系,這就是有人把IOC容器比喻成“粘合劑”的由來。
我們再來做個試驗:把上圖中間的IOC容器拿掉,然后再來看看這套系統。如下圖三
圖三:理想的系統
我們現在看到的畫面,就是我們要實現整個系統所需要完成的全部內容。這時候,A、B、C、D這4個對象之間已經沒有了耦合關系,彼此毫無聯系,這樣的話,當你在實現A的時候,根本無須再去考慮B、C和D了,對象之間的依賴關系已經降低到了最低程度。所以,如果真能實現IOC容器,對于系統開發而言,這將是一件多么美好的事情,參與開發的每一成員只要實現自己的類就可以了,跟別人沒有任何關系!
我們再來看看,控制反轉(IOC)到底為什么要起這么個名字?我們來對比一下:
軟件系統在沒有引入IOC容器之前,如圖1所示,對象A依賴于對象B,那么對象A在初始化或者運行到某一點的時候,自己必須主動去創建對象B或者使用已經創建的對象B。無論是創建還是使用對象B,控制權都在自己手上。
軟件系統在引入IOC容器之后,這種情形就完全改變了,如圖2所示,由于IOC容器的加入,對象A與對象B之間失去了直接聯系,所以,當對象A運行到需要對象B的時候,IOC容器會主動創建一個對象B注入到對象A需要的地方。
通過前后的對比,我們不難看出來:對象A獲得依賴對象B的過程,由主動行為變為了被動行為,控制權顛倒過來了,這就是“控制反轉”這個名稱的由來。
依賴注入(DI)
2004年,Martin Fowler探討了同一個問題,既然IOC是控制反轉,那么到底是“哪些方面的控制被反轉了呢?”,經過詳細地分析和論證后,他得出了答案:“獲得依賴對象的過程被反轉了”。控制被反轉之后,獲得依賴對象的過程由自身管理變為了由IOC容器主動注入。于是,他給“控制反轉”取了一個更合適的名字叫做“依賴注入(Dependency Injection)”。他的這個答案,實際上給出了實現IOC的方法:注入。所謂依賴注入,就是由IOC容器在運行期間,動態地將某種依賴關系注入到對象之中。
所以,依賴注入(DI)和控制反轉(IOC)是從不同的角度的描述的同一件事情,就是指通過引入IOC容器,利用依賴關系注入的方式,實現對象之間的解耦。
我們舉一個生活中的例子,來幫助理解依賴注入的過程。大家對USB接口和USB設備應該都很熟悉吧,USB為我們使用電腦提供了很大的方便,現在有很多的外部設備都支持USB接口。
圖四:USB接口和USB設備
現在,我們利用電腦主機和USB接口來實現一個任務:從外部USB設備讀取一個文件。
電腦主機讀取文件的時候,它一點也不會關心USB接口上連接的是什么外部設備,而且它確實也無須知道。它的任務就是讀取USB接口,掛接的外部設備只要符合USB接口標準即可。所以,如果我給電腦主機連接上一個U盤,那么主機就從U盤上讀取文件;如果我給電腦主機連接上一個外置硬盤,那么電腦主機就從外置硬盤上讀取文件。掛接外部設備的權力由我作主,即控制權歸我,至于USB接口掛接的是什么設備,電腦主機是決定不了,它只能被動的接受。電腦主機需要外部設備的時候,根本不用它告訴我,我就會主動幫它掛上它想要的外部設備。這就是我們生活中常見的一個依賴注入的例子。在這個過程中,我就起到了IOC容器的作用。
通過這個例子,依賴注入的思路已經非常清楚:當電腦主機讀取文件的時候,我就把它所要依賴的外部設備,幫他掛接上。整個外部設備注入的過程和一個被依賴的對象在系統運行時被注入另外一個對象內部的過程完全一樣。
我們把依賴注入應用到軟件系統中,再來描述一下這個過程:
對象A依賴于對象B,當對象 A需要用到對象B的時候,IOC容器就會立即創建一個對象B送給對象A。IOC容器就是一個對象制造工廠,你需要什么,它會給你送去,你直接使用就行了,而再也不用去關心你所用的東西是如何制成的,也不用關心最后是怎么被銷毀的,這一切全部由IOC容器包辦。
在傳統的實現中,由程序內部代碼來控制組件之間的關系。我們經常使用new關鍵字來實現兩個組件之間關系的組合,這種實現方式會造成組件之間耦合。IOC很好地解決了該問題,它將實現組件間關系從程序內部提到外部容器,也就是說由容器在運行期將組件間的某種依賴關系動態注入組件中。
IOC為我們帶來了什么好處
IOC在編程過程中不會對業務對象構成很強的侵入性,使用IOC之后,回想具有更好的可實行新,可重用性和可擴展性。
我們還是從USB的例子說起,使用USB外部設備比使用內置硬盤,到底帶來什么好處?
1、降低組件之間的耦合度
USB設備作為電腦主機的外部設備,在插入主機之前,與電腦主機沒有任何的關系,只有被我們連接在一起之后,兩者才發生聯系,具有相關性。所以,無論兩者中的任何一方出現什么的問題,都不會影響另一方的運行。這種特性體現在軟件工程中,就是可維護性,非常便于進行單元測試,便于調試程序和診斷故障。代碼中的每一個Class都可以單獨測試,彼此之間互不影響,只要保證自身的功能無誤即可,這就是組件之間低耦合或者無耦合帶來的好處。
2、提高開發效率和產品質量
USB設備和電腦主機的之間無關性,還帶來了另外一個好處,生產USB設備的廠商和生產電腦主機的廠商完全可以是互不相干的人,各干各事,他們之間唯一需要遵守的就是USB接口標準。這種特性體現在軟件開發過程中,好處可是太大了。每個開發團隊的成員都只需要關心實現自身的業務邏輯,完全不用去關心其它的人工作進展,因為你的任務跟別人沒有任何關系,你的任務可以單獨測試,你的任務也不用依賴于別人的組件,再也不用扯不清責任了。所以,在一個大中型項目中,團隊成員分工明確、責任明晰,很容易將一個大的任務劃分為細小的任務,開發效率和產品質量必將得到大幅度的提高。
3、統一標準,提高模塊的復用性
同一個USB外部設備可以插接到任何支持USB的設備,可以插接到電腦主機,也可以插接到DV機,USB外部設備可以被反復利用。在軟件工程中,這種特性就是可復用性好,我們可以把具有普遍性的常用組件獨立出來,反復利用到項目中的其它部分,或者是其它項目,當然這也是面向對象的基本特征。顯然,IOC不僅更好地貫徹了這個原則,提高了模塊的可復用性。符合接口標準的實現,都可以插接到支持此標準的模塊中。
4、模塊具有熱插拔特性
同USB外部設備一樣,模塊具有熱插拔特性。IOC生成對象的方式轉為外置方式,也就是把對象生成放在配置文件里進行定義,這樣,當我們更換一個實現子類將會變得很簡單,只要修改配置文件就可以了,完全具有熱插撥的特性。
以上幾點好處,難道還不足以打動我們,讓我們在項目開發過程中使用IOC框架嗎?
IOC總結
IOC控制反轉:說的是創建對象實例的控制權從代碼控制剝離到IOC容器控制,實際就是你在xml文件控制,側重于原理
DI依賴注入:說的是創建對象實例時,為這個對象注入屬性值或其它對象實例,側重于實現
?本文章參考于牧濤:http://www.cnblogs.com/superjt/p/4311577.html的文章
?
總結
以上是生活随笔為你收集整理的Spring---浅谈IOC的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 人体肝脏体积计算
- 下一篇: 欧洲统一语言参考标准C1,CEFR(欧洲