對象設計解耦的方法IOC和DI

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

面向對象的核心思想簡單來講就是把複雜系統分解成相互合做的對象,這些對象類經過封裝之後,內部實現對外部是透明的,從而下降了解決問題的複雜度,並且能夠靈活地被重用和擴展。IOC理論提出的觀點大致是這樣的:藉助於「第三方」實現具備依賴關係的對象之間的解耦,以下圖:編程

  因爲引進了中間位置的「第三方」,也就是IOC容器,使得A、B、C、D這4個對象沒有了耦合關係,齒輪之間的傳動所有依靠「第三方」了, 所有對象的控制權所有上繳給「第三方」IOC容器,因此,IOC容器成了整個系統的關鍵核心,它起到了一種相似「粘合劑」的做用,把系統中的全部對象粘合 在一塊兒發揮做用,若是沒有這個「粘合劑」,對象與對象之間會彼此失去聯繫,這就是有人把IOC容器比喻成「粘合劑」的由來。網絡

在沒有IOC容器以前,一個對象須要本身決定什麼時候、如何建立本身依賴的其它對象(所以須要知道要依賴引入對應的對象類),有IOC容器後,由它負責全部的對象的建立,並將每一個對象的依賴的其它對象關係注入,解決掉對象什麼時候、如何建立、如何注入其依賴對象的問題。即對象原來主動的控制本身的依賴對象變成了被動的由IOC容器動態的注入,所以IOC被叫作控制反轉。而IOC容器解決問題的本質是對象間的依賴關係、爲對象動態注入依賴的其它對象,從這個角度講又是依賴注入(DI)。所謂依賴注入,就是由IOC容器在運行期間,動態地將某種依賴關係注入到對象之中。因此,依賴注入(DI)和控制反轉(IOC)是從不一樣的角度的描述的同一件事情,就是指經過引入IOC容器,利用依賴關係注入的方式,實現對象之間的解耦數據結構

 IOC中最基本的技術就是「反射(Reflection)」編程,通俗來說就是根據給出的類名(字符串方式)來動態地生成對象。這種編程方式可讓對象在生成時才決定究竟是哪種對象。反射的應用是很普遍的,不少的成熟的框架,好比象Java中的Hibernate、Spring框架,.Net中 NHibernate、Spring.Net框架都是把「反射」作爲最基本的技術手段。
  咱們能夠把IOC容器的工做模式看作是工廠模式的昇華,能夠把IOC容器看 做是一個工廠,這個工廠裏要生產的對象都在配置文件中給出定義,而後利用編程語言的的反射編程,根據配置文件中給出的類名生成相應的對象。從實現來 看,IOC是把之前在工廠方法裏寫死的對象生成代碼,改變爲由配置文件來定義,也就是把工廠和對象生成這二者獨立分隔開來,目的就是提升靈活性和可維護 性。
使用IOC框架產品可以給咱們的開發過程帶來很大的好處,可是也要充分認識引入IOC框架的缺點,作到心中有數,杜絕濫用框架。
  第1、軟件系統中因爲引入了第三方IOC容器,生成對象的步驟變得有些複雜,原本是二者之間的事情,又憑空多出一道手續,因此,咱們在剛開始使用IOC框 架的時候,會感受系統變得不太直觀。因此,引入了一個全新的框架,就會增長團隊成員學習和認識的培訓成本,而且在之後的運行維護中,還得讓新加入者具有同 樣的知識體系。
  第2、因爲IOC容器生成對象是經過反射方式,在運行效率上有必定的損耗。若是你要追求運行效率的話,就必須對此進行權衡。
  第3、具體到IOC框架產品(好比:Spring)來說,須要進行大量的配製工做,比較繁瑣,對於一些小的項目而言,客觀上也可能加大一些工做成本。
  第4、IOC框架產品自己的成熟度須要進行評估,若是引入一個不成熟的IOC框架產品,那麼會影響到整個項目,因此這也是一個隱性的風險。
  咱們大致能夠得出這樣的結論:一些工做量不大的項目或者產品,不太適合使用IOC框架產品。另外,若是團隊成員的知識能力欠缺,對於IOC框架產品缺少深 入的理解,也不要貿然引入。最後,特別強調運行效率的項目或者產品,也不太適合引入IOC框架產品,象WEB2.0網站就是這種狀況。框架

所謂IoC,對於spring框架來講,就是由spring來負責控制對象的生命週期和對象間的關係。
Spring所倡導的開發方式就是如此,全部的類都會在spring容器中登記,告訴spring你是個什麼東西,你須要什麼東西,而後spring會在系統運行到適當的時候,把你要的東西主動給你,同時也把你交給其餘須要你的東西。全部的類的建立、銷燬都由 spring來控制,也就是說控制對象生存週期的再也不是引用它的對象,而是spring。對於某個具體的對象而言,之前是它控制其餘對象,如今是全部對象都被spring控制,因此這叫控制反轉。編程語言

    所謂的控制反轉,就是把原先咱們代碼裏面須要實現的對象建立、依賴的代碼,反轉給容器幫忙來實現。那麼必然的咱們須要建立一個容器,同時須要一種描述來讓容器知道須要建立的對象與對象的關係。這個描述最具體的表現就是咱們的配置文件。那麼就會有如下2個問題:學習

                      1.對象和對象的關係怎麼表示?網站

                          能夠用xml,properties等文件表示spa

                      2.描述對象關係的文件放在哪裏?.net

                          多是classpath,fileSystem,或者是URL網絡資源,ServletContext等

                  有了配置文件,還須要對配置文件進行解析,解析過程當中可能又會遇到如下幾個問題

                      1.不一樣的配置文件對對象的描述不同,如標準的,自定義聲明式的,如何統一?

                          使用Resource接口來統一

                      2.在內部須要有一個統一的關於對象的定義

                          統一使用BeanDefinition

                      3.如何對不一樣的配置文件進行解析?

                          使用BeanDefinitionReader和BeanFactory

 

                      4.須要對不一樣的配置文件語法,採用不一樣解析方式?

                          使用ApplicationContext

                  以上5個全是接口,都有各式各樣的實現,正是這5個接口定義了spring ioc容器的基本代碼組件結構,而其組件各類實現的組合關係組成了一個運行時的具體容器。

(1)Resource

                      是對資源的抽象,每個接口實現類都表明了一種資源類型,如ClasspathResource、URLResource、FileSystemResource等。每個資源類型都封裝了對某一種特定資源的訪問策略。它是spring資源訪問策略的一個基礎實現,應用在不少場景。

                    

 

        (2)BeanDefinition

                      又來抽象和描述一個具體bean對象。是描述一個bean對象的基本數據結構

 

        (3)BeanDefinitionReader

                      將外部資源對象描述的bean定義,統一轉化爲統一個內部數據結構BeanDefinition。對應不一樣的描述須要有不一樣的Reader。如XMLBeanDefinitionReader用來讀取xml描述配置的bean對象

                    

        (4)BeanFactory

                      用來定義一個很純粹的bean容器,它是一個bean容器的必備結構。同時和外部應用環境等隔離。BeanDefinition是它的基本數據結構。他維護一個BeanDefinitions Map,並能夠根據BeanDefinition的描述進行bean的建立和管理。

                                   

 

        (5)ApplicationContext

                      從名字上來看叫作應用上下文,是和應用環境息息相關的。這個就是咱們平時開發中常常直接使用的一個類,應用上下文,或者也叫作spring容器。其實它的基本實現是會持有一個BeanFactory對象,並基於此提供一些包裝和功能擴展。爲何要這麼作呢?由於BeanFactory實現了一個容器基本結構和功能,可是與外部環境隔離。那麼讀取配置文件,並將配置文件解析成BeanDefinition,而後註冊到BeanFactory的這一個過程的封裝天然就須要ApplicationContext。ApplicationContext和應用環境息息相關,常見的實現類有ClassPathXMLApplicationContext、FileSystemXMLApplicationContext、WebApplicationContext等。ClassPath、xml、FileSystem等詞都表明了應用和環境相關的一些意思。

                            

 

                      以上5個組件基本表明了ioc容器的一個最基本組成,而組件的組合是放在ApplicationContext的實現這一層來完成的

                      以ClassPathXMLApplicationContext爲例,展現5個組件的組合關係

 Spring Ioc核心源碼解析                               

相關文章
相關標籤/搜索