Model-View-Controller (MVC) in iOS: A Modern Approach

原文連接ios


這篇文章將幫助你避免App中常見的致使不易擴展的錯誤。你將會學到當你建立一個App時該怎麼作,不應怎麼作的最佳實踐。安全

讀完這篇文章你能學到在app中使用最新最好的實踐。避免結構上的問題。網絡

MVC101

模型是數據存放的地方。持久化、模型對象、解析器和網絡相關代碼這些東西一般放在這裏。mvc

視圖是app的界面。這些類能被複用,通常不存放特定業務的邏輯。app

控制器在模型和視圖之間進行調解,典型的是經過代理模式。理想狀況下,控制器實體不會知道它處理的實體視圖。相反,它會經過代理和抽象視圖交流。單元測試

什麼去了哪兒?

儘管理解MVC的理論很容易,有時候在實際的場景指出什麼去了哪兒倒是比較複雜的。讓咱們花些時間關注一下。測試

視圖層

當一個用戶和你的App交互的時候,他們是在和視圖層交流。視圖被認爲是App中的「啞吧」部分,由於它不該該包含任何的業務邏輯。在代碼層面,你一般會看到:動畫

UIView子類。從基本的UIView子類到複雜的自定義UIControl。代理

一個UIViewController(有爭議)。因爲一個UIViewController和它本身的根視圖以及不一樣的生命週期強烈的耦合在一起,我我的認爲應該屬於這一層,可是並非全部人認同。cdn

動畫和控制器轉場。

UIKit/AppKit、Core Animation 和 Core Graphics的一部分。

不要爲了節省時間把一堆代碼都寫到UIViewController裏,之後你可能會花多倍的時間來找bug,或者複用裏面的代碼。

用下面的清單檢查你的視圖層

它和模型層交互了嗎?

它是否包含了任何的業務邏輯?

它是否作了和UI無關的事情?

若是上面任何一個問題的答案是yes,那麼你就可能須要清理一下並重構了。

固然,這些規則沒有被刻在石頭上,有時你得彎曲它們。儘管如此,你得展示足夠的重視。

控制器層

控制器層是app裏最少複用的部分。由於它引入了你特定領域的規則。有些東西在你的app裏有意義,可是在別人的app裏面可能沒有什麼意義,這並不使人吃驚。

一般你會看到這一層的類決定着下面這些事情:

什麼應該首先進入:持久化仍是網絡?

你應該多久刷新一次app?

下一屏應該是什麼,在什麼樣的情況下?

若是app進入後臺,什麼應該被清理掉?

你應該把控制器看作app的大腦:它決定接下來發生什麼。一般你會想要對這些類作大量測試以確保全部的事情按照預期運行。

建議老是讓控制器是可注入的。這樣,你的UIViewController的擁有者就能提供控制器。這有兩方面的好處:

一、便於測試。

二、這些層會很乾淨,而且去耦合。這有助於定義職責,從而造成總體上更健康的代碼基礎。

模型層

模型層並非像它看起來的那麼可以自解釋。

就如同你指望的那樣,它將包含你的模型對象,基本覆蓋了大部分層的界面。

MVC: Massive View Controller?

UIViewController過多的承擔並不屬於它的職責,最終致使Massive View Controller。它開始於積累像網絡請求和數據解析這樣的事情,最終愈來愈大以致於你失去了對信息流的追蹤。更糟糕的是,你不能以一種安全的方式進行重構。由於這種方式會讓單元測試變得很是困難。

針對臃腫的控制器的解決方案很難快速找到解決方案。所以它經常變成技術債務。這在iOS社區很常見,也是MVC名聲被搞壞的緣由。可是這不是你的命運!

做爲一個通常原則,一個UIViewController不該該擁有超過130行代碼。這彷佛很那實現,可是若是你堅持原則,這很容易。如下是我堅持的一些原則:

一、view controller裏的大部分代碼和它的根視圖UIView的自定義有關。

二、它應該負責把控制器和它的根視圖勾連起來,例如,在一個IBAction上調用控制器方法。

三、UITableDataSource, UITableViewDelegate和其餘的一些代理不該放在它裏面。若是這樣作,就沒辦法測試它們。

四、若是你的view controller裏有過多的屬性,你能夠把他們分開到多個控制器中,或者建立一個自定義的UIView。

這些只是指導方針。有時你的UIViewController很是簡單,可能就不必建立那麼多實體。

記住,你賦予view controller的每個職責都會讓你喪失測試和複用那段代碼的機會。

相關文章
相關標籤/搜索