我司產(chǎn)品屬于初創(chuàng)項目亿絮,早期業(yè)務(wù)相對簡單明吩,最初項目中采用了簡單的MVC設(shè)計模式践剂。然而隨著業(yè)務(wù)邏輯增多圾笨,某些Controller變得十分臃腫媳握。
眾所周知阵面,MVVM模式解決了Controller的臃腫并方便單元測試芋齿,為了方便后續(xù)代碼維護锥累,在上版本新功能開發(fā)中才沧,項目開始使用MVVM模式進行開發(fā)迈喉。
但從上圖可以看出,MVVM模式中温圆,Controller即便清爽了挨摸,但無疑是將臃腫的代碼移到了ViewModel中。
上述上個版本所開發(fā)的新功能為“愛瘋搶”岁歉,從業(yè)務(wù)交互及界面狀態(tài)展現(xiàn)來看得运,有多個界面存在相同的業(yè)務(wù)交互和元素展現(xiàn),比如正在瘋搶列表锅移、瘋搶商品詳情熔掺、我關(guān)注的瘋搶、我參與的瘋搶等等非剃,這些界面都存在搶拍置逻、提醒、取消提醒备绽、關(guān)注券坞、取消關(guān)注、購買肺素、支付已搶拍成功商品等業(yè)務(wù)交互恨锚,同時按鈕展現(xiàn)(搶拍、提醒等狀態(tài)切換)及時間展現(xiàn)(搶拍開始時間倍靡、搶拍中倒計時眠冈、下次搶拍時間)等展示邏輯也無差別。
因此,結(jié)合這些具體情形蜗顽,我在模塊類設(shè)計時布卡,決定將這些公有的業(yè)務(wù)交互及界面展現(xiàn)狀態(tài)轉(zhuǎn)換邏輯抽離出來。依照MVVM設(shè)計模式雇盖,這些邏輯代碼理應(yīng)放到ViewModel中忿等。
但從實際出發(fā),如果將所有的邏輯的都放進ViewModel崔挖,將導致ViewModel變得十分臃腫贸街,同時使得具體業(yè)務(wù)邏輯代碼不夠粒度化,這樣無疑在代碼上耦合嚴重狸相、不利于代碼擴展及重復利用薛匪。
舉個例子,假如某些界面出現(xiàn)不同的展現(xiàn)方式及邏輯脓鹃,但卻具有相同的業(yè)務(wù)交互邏輯(搶拍逸尖、提醒、關(guān)注等)瘸右,針對這種情況娇跟,就不能共用同一個ViewModel來滿足了,這時不得不新寫一個ViewModel來包含不同的展現(xiàn)邏輯和相同的業(yè)務(wù)交互邏輯太颤,這無疑導致編寫重復的業(yè)務(wù)交互代碼苞俘,增加代碼維護成本。
為了ViewModel最終不變得臃腫龄章,同時利于代碼擴展及重復利用吃谣,我想到將ViewModel的職責更進一步細化,ViewModel負責網(wǎng)絡(luò)請求及界面展示邏輯做裙,而將業(yè)務(wù)交互部分單獨再抽出來岗憋,將其封裝在獨立的業(yè)務(wù)交互處理類Manager(或許這里取名Manager不恰當,暫且先這樣)當中菇用。
這樣澜驮,不同展現(xiàn)邏輯但具有相同業(yè)務(wù)交互邏輯的界面即可使用不同的ViewModel而共用同一個Manager了陷揪,滿足了一份業(yè)務(wù)交互邏輯代碼可以多處使用惋鸥、多處組裝,在一定程度上不僅降低了開發(fā)工作量悍缠,同時增強了代碼的可維護性卦绣。
我將這種演化后的模式稱為MVVM+Manager模式,簡稱為MVVMM飞蚓。Manager既然負責業(yè)務(wù)交互邏輯滤港,這其中的業(yè)務(wù)就少不了和服務(wù)器交互、和本地數(shù)據(jù)交互等,因此溅漾,MVVMM模式的示意圖可以定義為如下所示:
為了更具體說明MVVMM模式各個部分職責山叮,我寫了一個簡明的邏輯描述Demo供參考。
對于復雜的功能模塊添履,ViewModel仍然顯得很臃腫的話屁倔,可繼續(xù)將其職責再細化,例如將網(wǎng)絡(luò)請求邏輯也從ViewModel中抽離出來單獨成為一個處理類暮胧,類似猿題庫中即使用單獨的DataController類來負責網(wǎng)絡(luò)數(shù)據(jù)請求锐借,詳情可以參考博文。
上述有不足或疑問之處請留言交流往衷。
MVVMM Demo:
https://github.com/peterlogme/MVVMM.git
參考:
MVVM模式:
http://www.sprynthesis.com/2014/12/06/reactivecocoa-mvvm-introduction
http://yulingtianxia.com/blog/2015/05/21/ReactiveCocoa-and-MVVM-an-Introduction/
猿題庫MVVM設(shè)計博文:
http://gracelancy.com/blog/2016/01/06/ape-ios-arch-design/