[iOS-Practice] 項目結構

總結時讀到的一系列文章

iOS應用架構談 開篇
我的iOS工程結構
iOS項目的目錄結構-原創
iOS 項目的目錄結構能看出你的開發經驗
iOS項目的目錄結構

分層

三層架構 / MVC模式

Cocoa Core Competencies > Model-View-Controller
Concepts in Objective-C Programming > Model-View-Controller
淺談三層結構與MVC模式的區別

三層架構是一種軟件抽象的層次結構,是對復雜軟件的一種縱向切分,每一層次中完成同一類型的操作,以代碼的功能作為依據來分割,以降低軟件的復雜度,提高其可維護性。一般來說,層次之間是向下依賴的,下層代碼未確定其接口前,上層代碼是無法開發的,下層代碼接口的變化將使上層的代碼一起變化。

三層架構一般分別是數據訪問層、邏輯業務層和展示層。數據訪問層直接跟數據庫交互,負責數據的管理,與上層業務邏輯層交流時,通過數據對應的實體模型(model 類)。邏輯業務層則根據業務需求再對數據實體進行加工處理。而展示層則是面對用戶的,是加工過后的數據的外殼。展示層可能是 web 頁面,也有可能是其他客戶端,比如移動應用。服務端通過提供 API 接口,更多的承擔的是數據訪問層和邏輯業務層的角色。

而 MVC 則是針對展示層的一種復合設計模式。它通過數據在展示層的流動方向來將代碼分離成各個層次模塊。首先是 Model 層,它對接了獲取數據的 API 接口,即服務器端的邏輯層,這里 Model 層區別于三層架構中數據載體的實體模型 model,Model 層通過網絡請求或者從本地獲取數據,之后再對數據進行相關業務邏輯和其他的公共處理(如轉換為實體類),然后交給 Controller。其實如果是調用 API 網絡請求獲取數據時,主要的邏輯操作可能是在服務端完成的,本地
Model 層的作用有時候可能僅僅是轉換數據類型。View 層的任務是單純的渲染出界面展示數據,或提供界面改變展示方式(如動畫)的接口供給 Controller 調用。所以 Controller 就成為了 Model 層和 View 層之間的橋梁,數據從 Model 層流向 Controller,Controller 層決定如何調用 Model 層來獲取或修改數據,并最終讓 View 層展示數據,即數據最終流向 View 層。用戶通過界面和系統交互后的數據反饋給服務器或持久化存儲在本地,則是上述流向的逆過程。所以,一般 Controller 應該是小巧,簡單的,它主要的功能應該是負責數據與展示引擎之間的調度。MVC 模式中的三個層間其實并不存在明顯的層次結構,沒有明顯的向下依賴關系,他們更像是橫向的切分。

iOS 中的分層

作為客戶端開發的 iOS 應用,蘋果公司本身通過 SDK 就已經將 MVC 模式的思想植入其中。

Controller

通過 UIViewController 作為基類,實現了界面的控制器。

View

通過 .xib 或 .storyboard 文件和繼承 UIView 基類的視圖類來實現 View 層。

Model

一般應用對于數據的處理,主要分為兩部分,網絡請求和本地數據。網絡請求就是把數據的邏輯處理放在了服務器端,然后通過提供 API 接口給客戶端來進行數據交換。而本地數據的處理相當于是要在客戶端本地做類似服務器端的數據維護的工作,當然客戶端的復雜度級別要比服務端低很多。

所以在分模塊時,我們首先應把代碼職責分為網絡請求模塊和本地數據模塊。網絡請求模塊內封裝了請求 API 的代碼。而本地數據模塊可以考慮像服務器端一樣采用三層架構思想,數據訪問層 Dao 只負責數據的存取,向上層屏蔽掉具體的存儲方式,對于 iOS 來說包括NSUserDefault、.plist 文件和數據庫等,在邏輯業務層 Service 根據業務需求再對數據加工處理。

網絡請求模塊和本地數據模塊相當于是 Model 層,它們負責了數據的邏輯處理。這兩個模塊返回的邏輯處理后的數據都應該是原始的類型,并不轉換為實體類,這種把職責分離的設計使得 Controller 層的操作更靈活。可以根據需求實現不同的適配器,以用來轉換數據,比如當不同的 Controller 從同一個 Model 拿到數據后,可以通過不同的適配器轉換為最終需要提供給 View 層的數據格式,可能是實體類,也可能是其他數據結構。這種方式并沒有使 Model 層的代碼侵入到 Controller 層內,Controller 層仍只是負責調配,適配器其實也屬于 Model 層的一部分,只是這樣的實現提高了靈活性。Controller 層從 Model 層獲取數據的方式就是,先拿到原始數據,再按照需要組裝合適的適配器,最終輸出提供給 View 層的數據。

目錄結構劃分

iOS 工程中沒有嚴格的分包機制,一般通過 Group 的方式在工程中實現邏輯目錄劃分,方便代碼的組織和管理,使工程結構清晰和易于理解。應該在項目目錄中建立與 Group 對應的目錄,使代碼文件的劃分更清晰。一種快捷的操作是,先在磁盤上創建對應的文件夾,再把文件夾拖進 Xcode 項目中對應的位置,并選擇 Create groups for any added folders,這樣就創建了對應目錄的 Group。

根據上述對 MVC 模式的理解,以其為基礎可細分為:

  • Application,與整個應用相關的文件,包括 AppDelegate 文件,main.m,項目配置文件(Info.plist),自定義的配置文件(.plist),老項目中的預編譯文件。
  • Module,按功能模塊劃分,每一個模塊內再根據 MVC 模式分出 Controller 和 View 目錄。View目錄中存放的就是自定義的 view 類和 .xib 或 .storyboard 文件。除了功能模塊,還需要有一個 Base 模塊,用來存放一些需要繼承的 base 類以及一個 Common 模塊,用來存放一些各模塊共用的組件。實體類并不屬于某一個界面,所以應該單獨放在外層。如果是某一個 Controller 不使用實體類,而是需要定制的適配器,可以在模塊內添加 Adaptor 目錄,目錄內實現 Controller 對應的適配器。
  • Network,主要是對使用 AFNetworking 進行 API 請求的封裝。
  • Persistence,本地持久化數據的處理,如上所述分為 Dao 和 Service 兩層
  • Model,數據的實體模型類,描述系統中的一些角色和業務,同時可作為適配器類,提供與網絡請求層或數據持久化層提供的原始數據相互轉換的方法。
  • Category,存儲對現有系統類和自定義類的擴展。同一個類的擴展也盡量按處理的方向不同分為多個擴展來寫,這樣使模塊粒度更小,使用更方便。
  • Utility,系統常用工具類。同樣應該按處理的方向不同盡量拆分為更小的模塊。
  • Constant,只有一對 Constant 文件,用來存放項目中一些公用的常量。使用某一個類時才會用到的常量不放在這個文件里,而是應放在對應類的文件中。
  • Localizable,存放所有的用于國際化的 .strings 文件,一般主要分為各功能模塊,common,network提示信息等幾部分。
  • Vendor,存放不支持 Cocoapods 的第三方類庫。
  • Resource,存放多媒體資源,非 .png 格式的圖片文件。圖片資源用 Asset Catalog 管理(ios開發-圖片資源管理)
功能模塊與 MVC

在主體功能代碼與 MVC 模式劃分的層級關系上,除了上述使用的外層以功能模塊分組,每一個功能分組內,再劃分為 View 層和 Controller 層的方式外,還有另一種是外層以 Model、View、Controller 劃分,在 View 層和 Controller 層內再以功能模塊對代碼分組。選擇先按照功能模塊分組的原因是,這樣的劃分粒度更細,更便于組織管理。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容