關於iOS中MVC和MVVM的一些思考


 事情從一般開發中一個massive viewController說起,一個巨大的vc一般少則上千行代碼,多則上萬行。
 這中情況下對代碼的維護有致命性的障礙,個人親身體驗。
 當你試着從6000行的代碼中去找到一個網絡請求,找到相關的實現邏輯,這已經能夠讓你眼花繚亂的。
 更進一步,如果你打算對某個邏輯,某個場景進行測試,那事情的困難程度非常大。
 再者,如果你想重用某一部分的場景邏輯,那幾乎不可能,因爲所有的代碼都耦合在一個vc中了。


 爲什麼會造成一個vc的代碼這麼多,這麼複雜呢?
 一般有以下原因:
 1.view的構建:不管是用IB還是手寫界面,初學者一般是將界面構建的代碼放在vc中,甚至在vc的生命週期函數中,這是踏出massive viewController的第一步。
 2.網絡數據的請求及後續處理:網絡請求是一個比較關鍵的地方,涉及到數據的處理。我們在MVC模式下做個討論,首先是View,View作爲界面實現對象,一般能夠用MVC的人不會把網絡請求放裏面了,這個跳過。接下來是model,一般MVC中model作爲模型實體類,用於存放實體信息,執行實體的某些行爲,本地數據庫的操作,如果把網絡請求放到model中執行,網絡數據需要異步執行,如果model生命時間比網絡數據請求時間長,那還可以,但是一般的服務器返回json數據中包含的實體信息非常多甚至一些無關model的請求,這部分又是一個問題,所以model裏做網絡顯得格格不入,最後只能用vc,這是massive viewController的第二步。
 3.響應邏輯:在vc中常常會有對用戶事件作出的相應代碼以及delegate方法,這部分代碼中往往包含着複雜的判斷邏輯及數據處理代碼,這是massive viewController的第三步。
 4.數據源方法:典型的tableView會有datasource方法,其中數cellForRowAtIndexpath最爲典型,其中數據展示前的代碼也是非常多,massive viewController的第四步。
 5.本地數據庫操作:不多解釋,massive viewController第五步。
 6.其它無關vc的代碼:其它的比如有點工具性質及其他的代碼。於是66大順,一個massive viewController形成。


 上面列舉這麼多原因,無非想說明一個massive viewController的由來,就像剖析一個人的成功經歷一樣。
 那麼接下來重點就是如何解決這煩人的massive viewController了,爲了實現一個輕量級viewController。


 既然有原因,那麼解決辦法就從原因入手吧,先後順序不定,結合MVC模式(Model+View+Controller),不懂的自行google。
 1.view的處理:個人愚見,一般的做法是從vc中分離出一個主要的view類,如果view類中有其他的複雜的view,那麼繼續向下分離。我們可以模擬UIKit的做法,一個原則就是大的view構造成像tableView等視圖一樣,小的view構造成一個控件如tabbar之類,再把相關視圖可能做出的點擊效果和實現邏輯封裝在類中,留出接口,定製一些協議,執行代理方法數據源方法,這樣的話不僅減輕了viewController的負擔,而且還大大提高view對象的封裝性及可重用性,比如你想在不同的vc上使用同一個view,那麼你不用再去重寫,只需根據已有的接口和代理,數據源方法來實現相關邏輯即可。


 2.網絡數據的處理,這個放後面的MVVM討論。
 4.數據源方法:繼續分離vc的職責,分離出功能單一的dataSource,再把相關的數據傳遞過去,相關的處理邏輯block傳遞過去。其他的數據處理部分照樣留下面MVVM介紹。


 5.本地數據庫操作:在MVC模式下,這部分代碼應該封裝到model中,在vc裏調用相關接口即可。


 3.響應邏輯:經過對view的封裝,相關的響應方法已經比較清晰,但是其中的響應邏輯還未處理,其實無非是對數據進行處理,因爲視圖展示效果已經封裝到view類中了。對於本地數據的操作可以調用model的方法進行操作。


 6.對於一些無關vc的代碼,如果可以重用,那麼應該在項目中添加在Util目錄中,以做工具類使用。


 接下來介紹MVVM模式,MVVM = Model + View + ViewModel,當然在iOS中還有一個viewController。
 相比起MVC,MVVM多了一個viewModel,而重點就在於viewModel。
 顧名思義,viewModel即視圖模型,對視圖展示數據進行處理,一般流程是,接受vc的事件命令請求及處理相關數據,完事之後將標準展示數據處理好交給vc展示到view上,此謂視圖模型。將視圖模型分離出來,與視圖類做法類似,留出操作接口,協議及代理,這樣一來,對於數據層又可以重用,只要vc符合相關的協議,那麼在不同的vc中就可以用同一個viewModel了。封裝性和重用性得以體現,而且便於測試。


 借用歪果人的回答就是:
  Views display a certain shape of data. They have no idea where the data comes from.
ViewModels hold a certain shape of data and commands, they do not know where the data, or code, comes from or how it is displayed.
Models hold the actual data (various context, store or other methods)
Controllers listen for, and publish, events. Controllers provide the logic that controls what data is seen and where. Controllers provide the command code to the ViewModel so that the ViewModel is actually reusable.


這樣一來,我們可以把數據有效性的驗證,視圖的展示邏輯,網絡數據請求及處理,其他的數據處理邏輯集合到viewModel中。
上文中的問題得以解決:
2.網絡數據的處理:在viewModel中構建相關網絡請求邏輯並將加載完的數據進行處理及本地保存,用代理方法通知vc執行數據展示。
4.數據源方法:在viewModel中我們可以構建一些接口來封裝heightForRowAtIndexpath,numberOfRowInSection方法裏的展示邏輯,進而把validation data的代碼封裝起來。
5.本地數據庫操作:作爲連接model和vc的中間樞紐,本地數據庫的操作應該封裝到viewModel中的數據處理邏輯上。


MVVM的介紹及解決massive viewController問題大概這麼多。附上一些介紹鏈接:
objc.io,http://www.teehanlax.com/blog/model-view-viewmodel-for-ios/


說了這麼多,說點總結性的東西。
MVC和MVVM的區別和共同點。
區別:
優點:MVVM就是在MVC的基礎上加入了一個視圖模型viewModel,用於數據有效性的驗證,視圖的展示邏輯,網絡數據請求及處理,其他的數據處理邏輯集合,並定下相關接口和協議。相比起MVC,MVVM中vc的職責和複雜度更小,對數據處理邏輯的測試更加方便,對bug的原因排查更加方便,代碼可閱讀性,重用性和可維護性更高。MVVM耦合性更低。MVVM不同層級的職責更加明確,更有利於代碼的編寫和團隊的協作。
缺點:MVVM相比MVC代碼量有所增加。MVVM相比MVC在代碼編寫之前需要有更清晰的模式思路。




共同點:
優點:都有Model,View,ViewControlelr三個基礎層次,對於視圖封裝都比較好。都有一定可閱讀性。都低耦合性。都有利於代碼的維護。各部分的職責分明,便於測試,將大的解決方案化小,有利於團隊相互協作。
缺點:所謂的MVC和MVVM沒有很明確的定義,在不同平臺上更是如此,一千個人有一千個MVC和MVVM的理解,造成理解的困難。代碼相比以前會有一定量的增加。


本文總結:
打造一個輕量級的ViewController從Massive ViewControlelr 問題說明出發,剖析原因,再提出對vc進行職責分離,如分離出model,dataSource,Util工具等,再到MVC中討論問題的解決辦法,進而到MVC的升級版MVVM的問題解決思路。總體上,一個輕量級的ViewController構造思路是這樣,存在既有道理,MVC和MVVM有優點也有缺點,但缺點在他們所帶來的好處面前時不值一提的。他們的低耦合性,封裝性,可測試性,可維護性和多人協作便利大大提高了開法效率。
一句話總結就是,一個輕量級的ViewController是基於MVC和MVVM模式進行代碼職責的分離而打造的。


時間有限,代碼就不貼了。
相關參考和鏈接附上
1.objc.io
2.http://www.teehanlax.com/blog/model-view-viewmodel-for-ios/
3.stackoverflow:different between MVC MVVM, advantage of MVC,advantage of MVVM
4.github:C-41,MVVM模式的開源項目
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章