淺談IOC

1.IOC的理論背景php

2.什麼是IOChtml

3.IOC也叫依賴注入(DI)web

4.IOC的優缺點spring

5.IOC容器的技術剖析編程

6.IOC容器的一些產品架構

7.參考博文框架

本文旨在用語言(非代碼)說清楚IOC究竟是什麼,沒有什麼高深的技術,園中的老牛、大蝦們看到這裏能夠繞行了,以避免浪費您寶貴的時間。IOC這個東西DebugLZQ早就想寫了,可是出於對文章權威性的考慮(不能誤人子弟- -!),本文主要內容來源於最近LZ看的一些國內外的關於IOC的博文、博問,全部引用到的文章,在參考博文中均已註明。ide

1.IOC的理論背景

咱們知道在面向對象設計的軟件系統中,它的底層都是由N個對象構成的,各個對象之間經過相互合做,最終實現系統地業務邏輯[1]。post

  圖1 軟件系統中耦合的對象學習

  若是咱們打開機械式手錶的後蓋,就會看到與上面相似的情形,各個齒輪分別帶動時針、分針和秒針順時針旋轉,從而在錶盤上產生正確的時間。圖1中描述的就是這樣的一個齒輪組,它擁有多個獨立的齒輪,這些齒輪相互齧合在一塊兒,協同工做,共同完成某項任務。咱們能夠看到,在這樣的齒輪組中,若是有一個齒輪出了問題,就可能會影響到整個齒輪組的正常運轉。

  齒輪組中齒輪之間的齧合關係,與軟件系統中對象之間的耦合關係很是類似。對象之間的耦合關係是沒法避免的,也是必要的,這是協同工做的基礎。如今,伴隨着工業級應用的規模愈來愈龐大,對象之間的依賴關係也愈來愈複雜,常常會出現對象之間的多重依賴性關係,所以,架構師和設計師對於系統的分析和設計,將面臨更大的挑戰。對象之間耦合度太高的系統,必然會出現牽一髮而動全身的情形。

  圖2 對象之間的依賴關係

  耦合關係不只會出如今對象與對象之間,也會出如今軟件系統的各模塊之間,以及軟件系統和硬件系統之間。如何下降系統之間、模塊之間和對象之間的耦合度,是軟件工程永遠追求的目標之一。爲了解決對象之間的耦合度太高的問題,軟件專家Michael Mattson 1996年提出了IOC理論,用來實現對象之間的「解耦」,目前這個理論已經被成功地應用到實踐當中。

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容器,利用依賴關係注入的方式,實現對象之間的解耦。

  學過IOC的人可能都看過Martin Fowler(老馬,2004年post)的這篇文章:Inversion of Control Containers and the Dependency Injection pattern[2]。

  博客園的園友EagleFish(邢瑜琨)的文章: 深度理解依賴注入(Dependence Injection)[3]對老馬那篇經典文章進行了解讀。

    CSDN黃忠成的Inside ObjectBuilder[4]也是,不過他應該來自臺灣省,用的是繁體,看無論繁體中文的,能夠看園中的呂震宇博友的簡體中文版[轉]Object Builder Application Block[5] 。

4.IOC的優缺點

 In my experience, IoC using the Spring container brought the following advantages[6]:

  • flexibility
    • changing the implementation class for a widely used interface is simpler (e.g. replace a mock web service by the production instance)
    • changing the retrieval strategy for a given class is simpler (e.g. moving a service from the classpath to the JNDI tree)
    • adding interceptors is easy and done in a single place (e.g. adding a caching interceptor to a JDBC-based DAO)
  • readability
    • the project has one unified and consistent component model and is not littered with factories (e.g. DAO factories)
    • the code is briefer and is not littered without dependency lookup code (e.g. calls to JNDI InitialContext)
  • testability
    • dependencies are easy to replace mocks when they're exposed through a constructor or setter
    • easier testing leads to more testing
    • more testing leads to better code quality, lower coupling, higher cohesion

  使用IOC框架產品可以給咱們的開發過程帶來很大的好處,可是也要充分認識引入IOC框架的缺點,作到心中有數,杜絕濫用框架[1]。

    第1、軟件系統中因爲引入了第三方IOC容器,生成對象的步驟變得有些複雜,原本是二者之間的事情,又憑空多出一道手續,因此,咱們在剛開始使用IOC框架的時候,會感受系統變得不太直觀。因此,引入了一個全新的框架,就會增長團隊成員學習和認識的培訓成本,而且在之後的運行維護中,還得讓新加入者具有一樣的知識體系。

    第2、因爲IOC容器生成對象是經過反射方式,在運行效率上有必定的損耗。若是你要追求運行效率的話,就必須對此進行權衡。

    第3、具體到IOC框架產品(好比:Spring)來說,須要進行大量的配製工做,比較繁瑣,對於一些小的項目而言,客觀上也可能加大一些工做成本。

    第4、IOC框架產品自己的成熟度須要進行評估,若是引入一個不成熟的IOC框架產品,那麼會影響到整個項目,因此這也是一個隱性的風險。

    咱們大致能夠得出這樣的結論:一些工做量不大的項目或者產品,不太適合使用IOC框架產品。另外,若是團隊成員的知識能力欠缺,對於IOC框架產品缺少深刻的理解,也不要貿然引入。最後,特別強調運行效率的項目或者產品,也不太適合引入IOC框架產品,像WEB2.0網站就是這種狀況。

5.IOC容器的技術剖析

  IOC中最基本的技術就是「反射(Reflection)」編程,目前.Net C#、Java和PHP5等語言均支持,其中PHP5的技術書籍中,有時候也被翻譯成「映射」。有關反射的概念和用法,你們應該都很清楚,通俗來說就是根據給出的類名(字符串方式)來動態地生成對象。這種編程方式可讓對象在生成時才決定究竟是哪種對象。反射的應用是很普遍的,不少的成熟的框架,好比象Java中的Hibernate、Spring框架,.Net中 NHibernate、Spring.Net框架都是把「反射」作爲最基本的技術手段。

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.參考博文

[1] 架構師之路(39)---IoC框架 ,王澤賓,CSDN, 2009.

[2] Inversion of Control Containers and the Dependency Injection pattern ,Martin Fowler,2004.

[3] 深度理解依賴注入(Dependence Injection),EagleFish(邢瑜琨), 博客園, 2007.

[4]Inside ObjectBuilder ,黃忠成, CSDN, 2006.

[5][轉]Object Builder Application Block ,呂震宇,博客園, 2006.

[6]link

相關文章
相關標籤/搜索