1. 程式人生 > >關於iOS中MVC和MVVM的一些思考

關於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模式的開源專案