架構師之路(39)---IoC架構

來源:互聯網
上載者:User

標籤:style   blog   http   java   使用   strong   

1 IoC理論的背景
    我們都知道,在採用物件導向方法設計的軟體系統中,它的底層實現都是由N個對象組成的,全部的對象通過彼此的合作,終於實現系統的商務邏輯。


 
圖1:軟體系統中耦合的對象


    假設我們開啟機械式手錶的後蓋,就會看到與上面類似的情形,各個齒輪分別帶動時針、分針和秒針順時針旋轉,從而在錶盤上產生正確的時間。圖1中描寫敘述的就是這種一個齒輪組,它擁有多個獨立的齒輪,這些齒輪相互齧合在一起,協同工作,共同完畢某項任務。我們能夠看到,在這種齒輪組中,假設有一個齒輪出了問題,就可能會影響到整個齒輪組的正常運轉。
    齒輪組中齒輪之間的齧合關係,與軟體系統中對象之間的耦合關係很相似。對象之間的耦合關係是無法避免的,也是必要的,這是協同工作的基礎。如今,伴隨著工業級應用的規模越來越龐大,對象之間的依賴關係也越來越複雜,常常會出現對象之間的多重依賴性關係,因此,架構師和設計師對於系統的分析和設計,將面臨更大的挑戰。對象之間耦合度過高的系統,必定會出現牽一髮而動全身的情形。

 

 

 
圖2:對象之間複雜的依賴關係


    耦合關係不僅會出如今對象與對象之間,也會出如今軟體系統的各模組之間,以及軟體系統和硬體系統之間。怎樣減少系統之間、模組之間和對象之間的耦合度,是軟體project永遠追求的目標之中的一個。為瞭解決對象之間的耦合度過高的問題,軟體專家Michael Mattson提出了IOC理論,用來實現對象之間的“解耦”,眼下這個理論已經被成功地應用到實踐其中,非常多的J2EE項目均採用了IOC架構產品Spring。


2 什麼是控制反轉(IoC)
    IOC是Inversion of Control的縮寫,多數書籍翻譯成“控制反轉”,還有些書籍翻譯成為“控制反向”或者“控制倒置”。
    1996年,Michael Mattson在一篇有關探討物件導向架構的文章中,首先提出了IOC 這個概念。對於物件導向設計及編程的基本思想,前面我們已經講了非常多了,不再贅述,簡單來說就是把複雜系統分解成相互合作的對象,這些對象類通過封裝以後,內部實現對外部是透明的,從而減少瞭解決這個問題的複雜度,並且能夠靈活地被重用和擴充。IOC理論提出的觀點大體是這種:藉助於“第三方”實現具有依賴關係的對象之間的解耦,例如以:

 


 圖3:IOC解耦過程


    大家看到了吧,因為引進了中間位置的“第三方”,也就是IOC容器,使得A、B、C、D這4個對象沒有了耦合關係,齒輪之間的傳動所有依靠“第三方”了,所有對象的控制權所有上繳給“第三方”IOC容器,所以,IOC容器成了整個系統的關鍵核心,它起到了一種類似“粘合劑”的作用,把系統中的所有對象粘合在一起發揮作用,假設沒有這個“粘合劑”,對象與對象之間會彼此失去聯絡,這就是有人把IOC容器比喻成“粘合劑”的由來。
我們再來做個實驗:把中間的IOC容器拿掉,然後再來看看這套系統:
 


圖4:拿掉IoC容器後的系統


    我們如今看到的畫面,就是我們要實現整個系統所須要完畢的所有內容。這時候,A、B、C、D這4個對象之間已經沒有了耦合關係,彼此毫無聯絡,這種話,當你在實現A的時候,根本無須再去考慮B、C和D了,對象之間的依賴關係已經減少到了最低程度。所以,假設真能實現IOC容器,對於系統開發而言,這將是一件多麼美好的事情,參與開發的每一成員僅僅要實現自己的類就能夠了,跟別人沒有不論什麼關係!
    我們再來看看,控制反轉(IOC)究竟為什麼要起這麼個名字?我們來對照一下:
    軟體系統在沒有引入IOC容器之前,1所看到的,對象A依賴於對象B,那麼對象A在初始化或者執行到某一點的時候,自己必須主動去建立對象B或者使用已經建立的對象B。不管是建立還是使用對象B,控制權都在自己手上。
    軟體系統在引入IOC容器之後,這樣的情形就全然改變了,3所看到的,因為IOC容器的增加,對象A與對象B之間失去了直接聯絡,所以,當對象A執行到須要對象B的時候,IOC容器會主動建立一個對象B注入到對象A須要的地方。
    通過前後的對照,我們不難看出來:對象A獲得依賴對象B的過程,由主動行為變為了被動行為,控制權顛倒過來了,這就是“控制反轉”這個名稱的由來。

 

3 IOC的別名:依賴注入(DI)
   2004年,Martin Fowler探討了同一個問題,既然IOC是控制反轉,那麼究竟是“哪些方面的控制被反轉了呢?”,經過具體地分析和論證後,他得出了答案:“獲得依賴對象的過程被反轉了”。控制被反轉之後,獲得依賴對象的過程由自身管理變為了由IOC容器主動注入。於是,他給“控制反轉”取了一個更合適的名字叫做“依賴注入(Dependency Injection)”。他的這個答案,實際上給出了實現IOC的方法:注入。所謂依賴注入,就是由IOC容器在執行期間,動態地將某種依賴關係注入到對象之中。

所以,依賴注入(DI)和控制反轉(IOC)是從不同的角度的描寫敘述的同一件事情,就是指通過引入IOC容器,利用依賴關係注入的方式,實現對象之間的解耦。
    我們舉一個生活中的範例,來協助理解依賴注入的過程。大家對USB介面和USB裝置應該都非常熟悉吧,USB為我們使用電腦提供了非常大的方便,如今有非常多的外部裝置都支援USB介面。

 


圖6:USB介面和USB裝置

 

    如今,我們利用電腦主機和USB介面來實現一個任務:從外部USB裝置讀取一個檔案。
    電腦主機讀取檔案的時候,它一點也不會關心USB介面上串連的是什麼外部裝置,並且它確實也無須知道。它的任務就是讀取USB介面,掛接的外部裝置僅僅要符合USB介面標準就可以。所以,假設我給電腦主機串連上一個隨身碟,那麼主機就從隨身碟上讀取檔案;假設我給電腦主機串連上一個外置硬碟,那麼電腦主機就從外置硬碟上讀取檔案。掛接外部裝置的權力由我作主,即控制權歸我,至於USB介面掛接的是什麼裝置,電腦主機是決定不了,它僅僅能被動的接受。電腦主機須要外部裝置的時候,根本不用它告訴我,我就會主動幫它掛上它想要的外部裝置,你看我的服務是多麼的到位。這就是我們生活中常見的一個依賴注入的範例。在這個過程中,我就起到了IOC容器的作用。
    通過這個範例,依賴注入的思路已經很清楚:當電腦主機讀取檔案的時候,我就把它所要依賴的外部裝置,幫他掛接上。整個外部裝置注入的過程和一個被依賴的對象在系統執行時被注入另外一個對象內部的過程全然一樣。
我們把依賴注入應用到軟體系統中,再來描寫敘述一下這個過程:
    對象A依賴於對象B,當對象 A須要用到對象B的時候,IOC容器就會馬上建立一個對象B送給對象A。IOC容器就是一個對象製造工廠,你須要什麼,它會給你送去,你直接使用即可了,而再也不用去關心你所用的東西是怎樣製成的,也不用關心最後是怎麼被銷毀的,這一切所有由IOC容器包辦。
    在傳統的實現中,由程式內部代碼來控制組件之間的關係。我們常常使用newkeyword來實現兩個組件之間關係的組合,這樣的實現方式會造成組件之間耦合。IOC非常好地攻克了該問題,它將實現組件間關係從程式內部提到外部容器,也就是說由容器在執行期將組件間的某種依賴關係動態注入組件中。

 

  4 IOC為我們帶來了什麼優點

     我們還是從USB的範例說起,使用USB外部裝置比使用內建硬碟,究竟帶來什麼優點?
     第一、USB裝置作為電腦主機的外部裝置,在插入主機之前,與電腦主機沒有不論什麼的關係,僅僅有被我們串連在一起之後,兩者才發生聯絡,具有相關性。所以,不管兩者中的不論什麼一方出現什麼的問題,都不會影響還有一方的執行。這樣的特性體如今軟體project中,就是可維護性比較好,很便於進行單元測試,便於偵錯工具和診斷故障。代碼中的每個Class都能夠單獨測試,彼此之間互不影響,僅僅要保證自身的功能無誤就可以,這就是組件之間低耦合或者無耦合帶來的優點。
     第二、USB裝置和電腦主機的之間無關性,還帶來了另外一個優點,生產USB裝置的廠商和生產電腦主機的廠商全然能夠是互不相干的人,各幹各事,他們之間唯一須要遵守的就是USB介面標準。這樣的特性體如今軟體開發過程中,優點但是太大了。每一個Team Dev的成員都僅僅須要關心實現自身的商務邏輯,全然不用去關心其他的人工作進展,由於你的任務跟別人沒有不論什麼關係,你的任務能夠單獨測試,你的任務也不用依賴於別人的組件,再也不用扯不清責任了。所以,在一個大中型項目中,團隊成員分工明白、責任明晰,非常easy將一個大的任務劃分為細小的任務,開發效率和產品品質必將得到大幅度的提高。
     第三、同一個USB外部裝置能夠插接到不論什麼支援USB的裝置,能夠插接到電腦主機,也能夠插接到DV機,USB外部裝置能夠被重複利用。在軟體project中,這樣的特性就是可複用性好,我們能夠把具有普遍性的經常使用組件獨立出來,重複利用到項目中的其他部分,或者是其他項目,當然這也是物件導向的基本特徵。顯然,IOC不僅更好地貫徹了這個原則,提高了模組的可複用性。符合介面標準的實現,都能夠插接到支援此標準的模組中。
     第四、同USB外部裝置一樣,模組具有熱插拔特性。IOC產生對象的方式轉為外置方式,也就是把對象產生放在設定檔中進行定義,這樣,當我們更換一個實現子類將會變得非常easy,僅僅要改動設定檔就能夠了,全然具有熱插撥的特性。
以上幾點優點,難道還不足以打動我們,讓我們在項目開發過程中使用IOC架構嗎?

5 IOC容器的技術剖析
    IOC中最主要的技術就是“反射(Reflection)”編程,眼下.Net C#、Java和PHP5等語言均支援,當中PHP5的技術書籍中,有時候也被翻譯成“映射”。有關反射的概念和使用方法,大家應該都非常清楚,通俗來講就是依據給出的類名(字串方式)來動態地產生對象。這樣的編程方式能夠讓對象在產生時才決定究竟是哪一種對象。反射的應用是非常廣泛的,非常多的成熟的架構,比方象Java中的Hibernate、Spring架構,.Net中 NHibernate、Spring.Net架構都是把“反射”做為最主要的技術手段。
    反射技術事實上非常早就出現了,但一直被忽略,沒有被進一步的利用。當時的反射編程方式相對於正常的對象產生方式要慢至少得10倍。如今的反射技術經過改良最佳化,已經非常成熟,反射方式產生對象和通常對象產生方式,速度已經相差不大了,大約為1-2倍的差距。
    我們能夠把IOC容器的工作模式看做是原廠模式的升華,能夠把IOC容器看作是一個工廠,這個工廠裡要生產的對象都在設定檔裡給出定義,然後利用程式設計語言的的反射編程,依據設定檔裡給出的類名產生對應的對象。從實現來看,IOC是把曾經在Factory 方法裡寫死的對象產生代碼,改變為由設定檔來定義,也就是把工廠和對象產生這兩者獨立分隔開來,目的就是提高靈活性和可維護性。
6 IOC容器的一些產品
    Sun ONE技術體系下的IOC容器有:輕量級的有Spring、Guice、Pico Container、Avalon、HiveMind;重量級的有EJB;不輕不重的有JBoss,Jdon等等。Spring架構作為Java開發中SSH(Struts、Spring、Hibernate)三劍客之中的一個,大中小項目中都有使用,很成熟,應用廣泛,EJB在關鍵性的工業級項目中也被使用,比方某些電信業務。
    .Net技術體系下的IOC容器有:Spring.Net、Castle等等。Spring.Net是從Java的Spring移植過來的IOC容器,Castle的IOC容器就是Windsor部分。它們均是輕量級的架構,比較成熟,當中Spring.Net已經被逐漸應用於各種項目中。
7 使用IOC架構應該注意什麼
    使用IOC架構產品可以給我們的開發過程帶來非常大的優點,可是也要充分認識引入IOC架構的缺點,做到心中有數,杜絕濫用架構。
    第一、軟體系統中因為引入了第三方IOC容器,產生對象的步驟變得有些複雜,本來是兩者之間的事情,又憑空多出一道手續,所以,我們在剛開始使用IOC架構的時候,會感覺系統變得不太直觀。所以,引入了一個全新的架構,就會添加團隊成員學習和認識的培訓成本,而且在以後的執行維護中,還得讓新添加者具備相同的知識體系。
    第二、因為IOC容器產生對象是通過反射方式,在執行效率上有一定的損耗。假設你要追求執行效率的話,就必須對此進行權衡。
    第三、詳細到IOC架構產品(比方:Spring)來講,須要進行大量的配製工作,比較繁瑣,對於一些小的項目而言,客觀上也可能加大一些工作成本。
    第四、IOC架構產品本身的成熟度等級須要進行評估,假設引入一個不成熟的IOC架構產品,那麼會影響到整個項目,所以這也是一個隱性的風險。
    我們大體能夠得出這種結論:一些工作量不大的項目或者產品,不太適合使用IOC架構產品。另外,假設團隊成員的知識能力欠缺,對於IOC架構產品缺乏深入的理解,也不要貿然引入。最後,特彆強調執行效率的項目或者產品,也不太適合引入IOC架構產品,象WEB2.0網站就是這種情況。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.