iOS應用千萬級架構:MVVM框架


業務模塊內的MVC和MVVM架構

目前,唯品會中MVC和MVVM架構並存,后期會偏重於MVVM架構的使用。

MVC架構

Model:程序中要操縱的實際對象的抽象,為Controller提供經過抽象的業務數據,供Controller調度

View:視圖,負責界面的元素的展示

Controller:控制器,管理View的聲明周期及子view的生成和組裝,負責Model和View之間的通信。

MVC框架的優勢:
1. 應用廣泛,幾乎所有前端語言都有類似MVC的設計痕跡
2. 設計思想非常簡潔,學習成本很低,新人上手非常容易。

MVC框架的問題:
MVC並沒有對數據請求和處理邏輯代碼應該放在哪一層做出明確地划分,因此一旦頁面邏輯或交互稍微復雜,Controller就會變得很臃腫,代碼也就越來越難維護。

MVVM架構

MVVM框架是在MVC的基礎上演化而來,MVVM想要解決的問題是盡可能地減少Controller的任務。

Model:程序中要操縱的實際對象的抽象
View(ViewController):MVVM中的View不再是UIView的子類,而變成了UIViewController的子類。這里的View實際上就是MVC中剝離了處理呈現View邏輯部分的Controller,因此它仍然有各種UIView的屬性,仍然有ViewController的聲明周期的各種方法,但是這里的Controller不再負責數據的請求以及處理邏輯,因此不再臃腫。
ViewModel:MVVM中,ViewModel代替了MVC中的Controller成為了協調者的角色,ViewModel被View(ViewController)持有,同時持有者Model。數據請求以及處理邏輯都放在ViewModel中,View(ViewController)就瘦了下來。

MVVM框架的優勢:
1. View(ViewController)通過對ViewModel中的數據進行綁定來更新界面,不用通過邏輯或者條件判斷來更新view,大大降低了復雜交互時出bug的幾率。
2. View(ViewController)中代碼簡潔,后期的維護和優化比較容易。

MVVM框架的問題:
學習成本比MVC高,如果對MVVM的職責划分理解不透徹,很容易導致ViewModel的存在形同虛設, 反而增加了維護的成本。

我們為什么要用MVVM?

訂單售后這個頁面內容非常多,而且里面的內容會變,還可以收縮展開,還會出現由接口請求成功或失敗來控制某一部分的顯示還是隱藏。當你使用普通的MVC架構的時候,你會發現,在controller里的代碼量非常驚人的,View的計算也非常復雜,當有一塊內容要在中間展示的時候,下面的所有的View的Y值都得重新計算。顯然,維護成本是非常高的,改動一個小點還可能會導致蝴蝶效應,測試也要回歸當前頁面所有的用例。

那有沒有好的辦法來解決這些問題呢?我只想在自己的小塊里加功能,當小塊的內容高度變化了,整個頁面的布局高度跟着自己變化呢。答案是有的,那就是使用MVVM模式。

看下圖的UML類圖,分析一下,如下:

下面就CollectionView做說明,每一個內容都是一個小塊Cell,都有自己的cellViewmodel,整個控制器有一個大的viewmodel,包裝所有的cellViewmodel,就這樣構建一個頁面。

1、itemCell 是小塊Cell,里面主要是初始化View,更新View的數據,需要返回cell的寬高

2、cellViewModel,是itemCell的ViewModel,給itemCell 提供數據,itemCell的點擊事件也是回調到cellViewModel中。

3、Cell1ViewModel 和 item1Cell 組成一個小塊Cell1

4、Cell2ViewModel 和 item2Cell 組成另一個小塊Cell2

5、ViewModel 網絡請求拿到數據之后,組裝上面的小塊Cell1ViewModel、小塊Cell2ViewModel,通過方法【 - (Class)cellClass 】就可以拿到當前的itemCell

6、ViewModel中,還通過block的方式,對Controller回調綁定了事件,比如cell的點擊事件、加載數據成功事件、按鈕點擊事件等

例子

Demo有兩種處理方式,一是通過繼承基類,重寫基類的方法來實現;二是通過協議,cell使用cellprotocol協議,cellModel使用cellModelProtocol協議。

基類與協議對比

基類:好處就是可以在基類里處理一下統一的UI,比如每個cell都帶圓角。劣:方法要子類去重寫,會導致在重寫的時候,類名寫錯的風險。

協議:定義好協議,由每個類實現,方法統一,不容易出錯。但沒辦法統一處理UI,要每個類實現協議之后,在協議方法里編寫。

基類+協議:用戶繼承基類,基類里面實現協議。層級太深,一層套一層,后面的人接手不好理解。

使用方法

直接繼承MVVMBase使用

  1. 新建一個控制器VSDemoCollectionViewController,繼承於VSMVVMCollectionViewController
  2. 新建一個該控制器的ViewModel(VSDemoCollectionViewModel),繼承於VSMVVMCollectionViewModel,負責管理所有的CellViewModel
  3. 新建一個CellModel(VSDemoCollectionItemCellModel),繼承於VSMVVMCollectionViewCellModel,負責管理元素Cell,在方法cellClass中,返回關聯的Cell(VSDemoCollectionItemCell)
  4. 新建一個Cell(VSDemoCollectionItemCell),繼承於VSMVVMCollectionViewCell,需要重寫VSMVVMCollectionViewCell中的方法,返回該cell的高度。
  5. 頁面很復雜,需要重新步驟3和4,不斷的拆分這個復雜的Cell.
  6. 最后,所有的cellModel都交由第2步的控制器的ViewModel整合加載。

源代碼

代碼Demo已經上傳到github: https://github.com/jiangys/VSMVVM 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM