本頁使用了標題或全文手工轉換

控制反轉

維基百科,自由的百科全書
跳至導覽 跳至搜尋

控制反轉(Inversion of Control,縮寫為IoC),是物件導向程式設計中的一種設計原則,可以用來減低電腦代碼之間的耦合度。其中最常見的方式叫做依賴注入(Dependency Injection,簡稱DI),還有一種方式叫「依賴尋找」(Dependency Lookup)。通過控制反轉,物件在被建立的時候,由一個調控系統內所有物件的外界實體,將其所依賴的物件的參照傳遞(注入)給它。

起源[編輯]

早在2004年,Martin Fowler就提出了「哪些方面的控制被反轉了?」這個問題。他總結出是依賴物件的獲得被反轉了,因為大多數應用程式都是由兩個或是更多的類通過彼此的合作來實現業務邏輯,這使得每個物件都需要取得與其合作的物件(也就是它所依賴的物件)的參照。如果這個取得過程要靠自身實現,那麼這將導致代碼高度耦合並且難以維護和除錯。

技術描述[編輯]

Class A中用到了Class B的物件b,一般情況下,需要在A的代碼中顯式的new一個B的物件。

採用依賴注入技術之後,A的代碼只需要定義一個私有的B物件,不需要直接new來獲得這個物件,而是通過相關的容器控制程式來將B物件在外部new出來並注入到A類里的參照中。而具體取得的方法、物件被取得時的狀態由設定檔(如XML)來指定。

實現方法[編輯]

實現控制反轉主要有兩種方式:依賴注入和依賴尋找。兩者的區別在於,前者是被動的接收物件,在類A的實例建立過程中即建立了依賴的B物件,通過類型或名稱來判斷將不同的物件注入到不同的屬性中,而後者是主動索取相應類型的物件,獲得依賴物件的時間也可以在代碼中自由控制。

依賴注入[編輯]

依賴注入有如下實現方式:

  • 基於介面。實現特定介面以供外部容器注入所依值型別的物件。
  • 基於 set 方法。實現特定屬性的public set方法,來讓外部容器呼叫傳入所依值型別的物件。
  • 基於建構函式。實現特定參數的建構函式,在新建物件時傳入所依值型別的物件。
  • 基於註解。基於Java的註解功能,在私有變數前加「@Autowired」等註解,不需要顯式的定義以上三種代碼,便可以讓外部容器傳入對應的物件。該方案相當於定義了public的set方法,但是因為沒有真正的set方法,從而不會為了實現依賴注入導致暴露了不該暴露的介面(因為set方法只想讓容器存取來注入而並不希望其他依賴此類的物件存取)。

依賴尋找[編輯]

依賴尋找更加主動,在需要的時候通過呼叫框架提供的方法來取得物件,取得時需要提供相關的設定檔路徑、key等資訊來確定取得物件的狀態

控制反轉應用實例[編輯]

C++[編輯]

  • PocoCapsule IoC and DSM framework LGPL開源的,支援完全非侵入C++的控制反轉(IoC)及領域特定建模(DSM)容器
  • hypodermic MIT開源協定,Hypodermic是一個基於C++11開發的控制反轉(IoC)容器,它為你的C++物件協同運作提供依賴注入。Hypodermic靈感來自著名的.NET IoC專案Autofac。

Java[編輯]

使用Java語言寫成的程式在控制反轉容器(Inversion of Control Container)裡應用了控制反轉(Martin 2004)。軟體需要一個來自容器的物件,而容器自行建構物件和它的附屬物。ATG英語Art Technology GroupDynamo 應用程式伺服器是第一個利用這途徑的環境之一,近來關於這些容器的例子包含了 HiveMindPicoContainer[永久失效連結]Spring Framework(注意 Spring 是一個完整的企業平台,而非 IOC容器)、Apache ExcaliburSeasarDPML Metro.

.NET[編輯]

PHP[編輯]

參考文件[編輯]

  1. ^ Robert Cecil Martin. Agile Software Development: Principles, Patterns and Practices. Pearson Education. 2002. ISBN 978-0-13-597444-5. 
  2. ^ Robert Cecil Martin. The Dependency Inversion Principle (PDF). [2005-11-15]. (原始內容 (PDF)存檔於2004-12-21). 
  3. ^ Martin Fowler. Inversion of Control Containers and the Dependency Injection Pattern. 2004 [2005-11-15]. 
  4. ^ Sony Mathew. Examining the Validity of Inversion of Control. 2005 [2005-11-16]. (原始內容存檔於2005-11-29). 
  5. ^ Ke Jin. Domain Specific Modeling (DSM) in IoC frameworks. 2007 [2007-11-13]. 

外部連結[編輯]

參考文獻[編輯]