類比Spring框架來實現OC中的依賴注入

若是你以前使用過JavaEE開發中的Spring框架的話,那麼你必定對依賴注入並不陌生。依賴注入(DI: Dependency Injection)控制反轉(IoC: Inversion of Control)的實現方式之一,另一種是依賴查找(DL: Dependency Lookup)。固然在Spring框架中主要使用到了控制反轉中的依賴注入這種方式。固然在Spring框架中除了依賴注入外,還有一個重要的概念那就是面向切面編程(AOP)html

簡單的說,依賴注入負責往類中注入依賴對象,而面向切面編程則負責往裏添加代碼段的。本篇博客咱們主要聊的就是依賴注入,關於AOP和依賴查找的內容,若是之後有機會,會在後邊的博客進行介紹。git

本篇博客不是使用Java語言實現的,而是使用Objective-C來實現的。實現依賴注入的具體方式就是使用反射機制來實現的,本篇博客,咱們就使用OC的反射機制來看一下iOS開發中的依賴注入的實現方式。固然在Java的Spring框架中是在XML文件中配置的JavaBean,入鄉隨俗,本篇博客咱們就使用iOS開發中經常使用的PList文件來存儲相似於JavaBean的東西,也就是數本篇博客咱們使用PList文件來代替XML文件。廢話少說,進入咱們的主題。github

 

1、依賴注入的實現機制編程

依賴注入,聽起來特別高大上,其實真正理解其工做原理後,也沒什麼東西。本篇博客採用的代碼實例與以前咱們聊「策略模式」的示例一致。關於以前的策略模式的博客,請移步於《「穿越火線」中的「策略模式」(Strategy Pattern)》。固然咱們以前的示例是使用的Swift來實現的,本篇博客使用的是OC, 雖然語言不通,可是思想是一致的。在「策略模式」中咱們經過策略模式爲不通的軍官提供不一樣的武器策略。而本篇博客,咱們依然採用這個思路,不過咱們是依照「依賴注入」的方式來爲不一樣的軍官提供不一樣的武器策略框架

下方就是咱們本篇博客使用示例的類圖。WeaponType是全部武器的父類,在其中扮演者「武器接口」的角色。全部的武器都繼承自WeaponType。而Character角色類依賴於WeaponType武器接口類,全部CharacterWeaponType存在依賴關係。post

  

 

依賴注入」從字面上看,就是注入依賴。也就是將依賴關係的對象注入到相應的類中。而在上述示例中,Character依賴於WeaponType接口,若是使用「依賴注入」來解決這層依賴關係的話,就是經過反射機制(「Runtime」)動態的將WeaponType的子類的對象注入到Character對應的依賴屬性中去而反射時須要的依賴關係信息,咱們就從PList文件中進行讀取,固然Java中是從XML中進行配置的,這就是「依賴注入」。url

本篇博客咱們就來根據上述類圖的依賴關係,來完整的實現這個實例。固然在真正實現時,咱們用到的主要核心內容是「面向接口編程」「面向對象的多態性」「反射機制」「PList文件的讀取與操做」。下方會一一介紹。spa

 

 

2、示例工程的目錄結構3d

接下來咱們就來概述一下本篇博客所使用到的實例的工程結構,也就是先總體的瞭解一下本篇博客所涉及的示例工程。下方這個工程目錄結構就是咱們本篇博客所涉及的示例的目錄結構。Weapon文件夾中存放的就是武器策略所涉及的武器接口與武器類。Character文件夾中存放的就是武器使用者所對應的目錄。PList文件則存儲的是Character類依賴WeaponType接口的具體類的依賴信息。Relation類則是負責讀取PList文件中的依賴信息,根據這些依賴信息將依賴對象經過「反射機制」注入到相應的類中。htm

  

 

 

3、PList文件中的內容

本篇博客中的PList文件的做用就相似於Spring框架中用來配置JavaBean的XML。固然咱們本篇博客的PList文件的存儲內容的結構與形式與Spring中的XML有所不一樣,可是其做用都是同樣的,都是用來描述類之間的依賴關係的。

下方截圖就是本篇示例所涉及的PList文件中的內容。從下方文件中,咱們能夠看出其中存儲了三個類的信息,一個是Lieutenant(中尉)類,一個是Captain(上尉)類,最後一個就是Soldier(士兵)類。每一個類也就是Java中常說的JavaBean,Relation類能夠根據反射機制根據這些類在PList文件中提供的信息來實例化相應的類的對象

咱們就以Lieutenant爲例。在PList文件中,其實Lieutenant就對應這一個類,從Lieutenant對應的信息來看,Lieutenant的對象由Character類實例化,可是在實例化時須要給Character的對象依賴屬性weapon賦一個HK48Weapon類的對象。固然這一系列實例化以及賦值的動做都是由反射機制完成。稍後咱們會給出具體實現。

  

 

 

4、經過PList文件建立類

Relation類就是賦值加載相應的PList文件內容,而後根據其加載的內容利用反射機制生成相應的類的對象。下方代碼片斷就是Relation類加載上述的PList文件內容,讓後給據這些內容生成相應的類的對象的。下方這個代碼片斷根據Relation提供的上下文分別建立了Lieutenant對象Captain對象以及Soldier的對象。具體以下所示。

  

根據上下文建立完對象後,都會調用fire方法,由於每一個對象對應的上下文不一樣,也就是注入的依賴對象不一樣,因此fire方法執行的結果也不一樣。下方是上述代碼的運行結果,以下所示:

  

 

 

 

5、使用反射機制注入依賴對象

接下來咱們就要來看一下如何使用反射機制來注入依賴對象的,也就是Relation類的具體實現。

1.經過初始化方法提供plist文件

下方是Relation類的構造器,構造器中有個參數plistFileName, 該參數就是用來存儲依賴上下文信息的plist文件。Relation類在實例化對象時,收到該文件後,會加載該文件中的上下文信息,也就是咱們plist文件中的內容。具體代碼以下所示。

  

 

下方代碼片斷就是本篇博客的核心代碼,根據PList文件中提供的上下文信息,生成相應的對象,並給對象相應的屬性注入依賴對象。固然下方是經過Setter方法來設置依賴對象的。設置完畢後,返回該注入好依賴的對象。具體以下所示。

  

 

今天博客就先到這兒吧,之後咱們找個合適的時間再聊聊依賴查找面向切面編程的東西。下方的github連接是本篇博客所涉及Demo的源碼分享連接,以下所示。

源碼的github分享連接:https://github.com/lizelu/DependencyInjectionForiOS 

相關文章
相關標籤/搜索