iOS-MVC,MVP,MVVM及VIPER簡(jiǎn)介

iOS中MVC,MVP,MVVM及VIPER設(shè)計(jì)模式介紹的文章有很多,開(kāi)發(fā)過(guò)程MVC最常見(jiàn)的模式,MVVM也經(jīng)常被在項(xiàng)目中實(shí)踐,關(guān)于MVP,VIPER基本屬于小眾范疇,實(shí)際項(xiàng)目中開(kāi)發(fā)的過(guò)程比較少.

MVC

MVC(Model-View-Controller)經(jīng)典的設(shè)計(jì)模式,iOS項(xiàng)目本身的模板天然的MVC設(shè)計(jì)模式.MVC是官方推薦的主流架構(gòu),隨著日常項(xiàng)目的開(kāi)發(fā),大家對(duì)以下MVC設(shè)計(jì)圖應(yīng)該不陌生.


MVC.png

Model--負(fù)責(zé)主要的數(shù)據(jù)或者操作數(shù)據(jù),緩存數(shù)據(jù).DataProvider和CacheData.
View--負(fù)責(zé)UI展示層,UIView,UITableView,UITableViewCell...
Controller--負(fù)責(zé)協(xié)調(diào) Model 和 View,ViewController負(fù)責(zé)Model和View之間的通信,及View視圖的事件響應(yīng).

Model,View與Controller三個(gè)模塊間相互都有通信,緊密耦合,降低三者之間的復(fù)用性.如果進(jìn)行項(xiàng)目開(kāi)發(fā)能夠控制的好,也能支撐項(xiàng)目不斷前進(jìn),實(shí)際開(kāi)發(fā)中MVC的更像下面的設(shè)計(jì)圖:


MVC.png

iOS中UIViewController相當(dāng)于View和Controller耦合,就容易造成控制器臃腫(Massive View Controller).MVC開(kāi)發(fā)過(guò)程能將模塊典型的分開(kāi),這是MVC的最大優(yōu)勢(shì),但是MVC模式下的測(cè)試性特別差,MVC模式下頁(yè)面UI測(cè)試如果進(jìn)行單獨(dú)測(cè)試非常困難,一般都是能簡(jiǎn)單的進(jìn)行接口層面的測(cè)試.可以嘗試將UIViewController的過(guò)于臃腫的UI邏輯和業(yè)務(wù)邏輯抽取出來(lái),雖然MVC只有三層,并不是說(shuō)開(kāi)發(fā)過(guò)程中只有這三層.

MVP

先來(lái)看一張MVP之間模塊通信圖:


MVP.png

MVP看起來(lái)和MVC特別像雙胞胎兄弟,最大的不同大于View和Model之間切斷了通信關(guān)系,嚴(yán)格的按照View->Presenter->Model的順序執(zhí)行,MVP中的協(xié)調(diào)器Presenter并沒(méi)有對(duì)ViewController的生命周期做任何改變,如果要進(jìn)行測(cè)試,我們只需要模擬Presenter中的數(shù)據(jù)給View即可.Presenter中沒(méi)有UI布局相關(guān)的代碼,只負(fù)責(zé)更新View的數(shù)據(jù)和狀態(tài),以及Model之間的通信.

iOS項(xiàng)目大多數(shù)是都是基于MVC開(kāi)發(fā)的,如果切換到MVP應(yīng)該是時(shí)間成本最小的,但是如果業(yè)務(wù)邏輯比較多,最終會(huì)造成Presenter的臃腫,本質(zhì)上沒(méi)有解決太多問(wèn)題.因此MVP項(xiàng)目相對(duì)于其他框架普及度不高.

MVVM

MVVM 模式將 Presenter 改名為 ViewModel,基本上與 MVP 模式完全一致,唯一的區(qū)別是,它采用雙向綁定(data-binding),View的變動(dòng),自動(dòng)反映在 ViewModel,ViewModel的變動(dòng)也會(huì)反應(yīng)在View上.

MVVM 在實(shí)際使用中,確實(shí)能夠使得 Model 層和 View 層解耦,但是如果你需要實(shí)現(xiàn) MVVM 中的雙向綁定的話(huà)可以通過(guò)開(kāi)源庫(kù)實(shí)現(xiàn):

基于KVO的綁定庫(kù) RZDataBindingSwiftBond

完全的函數(shù)響應(yīng)式編程,ReactiveCocoa、RxSwift或者 PromiseKit

FlyElephant.png

前端的AngularEmber 基于MVVM模式的開(kāi)發(fā).

<blockquote>MVVM 在實(shí)際使用中,確實(shí)能夠使得 Model 層和 View 層解耦,但是如果你需要實(shí)現(xiàn) MVVM 中的雙向綁定的話(huà),那么通常就需要引入更多復(fù)雜的框架來(lái)實(shí)現(xiàn)了。
對(duì)此,MVVM 的作者 John Gossman 的 批評(píng) 應(yīng)該是最為中肯的。John Gossman 對(duì) MVVM 的批評(píng)主要有兩點(diǎn):
第一點(diǎn):數(shù)據(jù)綁定使得 Bug 很難被調(diào)試。你看到界面異常了,有可能是你 View 的代碼有 Bug,也可能是 Model 的代碼有問(wèn)題。數(shù)據(jù)綁定使得一個(gè)位置的 Bug 被快速傳遞到別的位置,要定位原始出問(wèn)題的地方就變得不那么容易了。
第二點(diǎn):對(duì)于過(guò)大的項(xiàng)目,數(shù)據(jù)綁定需要花費(fèi)更多的內(nèi)存。
某種意義上來(lái)說(shuō),我認(rèn)為就是數(shù)據(jù)綁定使得 MVVM 變得復(fù)雜和難用了。但是,這個(gè)缺點(diǎn)同時(shí)也被很多人認(rèn)為是優(yōu)點(diǎn)。</blockquote>

VIPER

VIPER是劃分責(zé)任的粒度是很好的選擇,VIPER在責(zé)任劃分層面進(jìn)行了迭代,VIPER分為五個(gè)層次:

VIPER.png
  • 交互器(Interactor) -- 包括關(guān)于數(shù)據(jù)和網(wǎng)絡(luò)請(qǐng)求的業(yè)務(wù)邏輯,例如創(chuàng)建一個(gè)實(shí)體(數(shù)據(jù)),或者從服務(wù)器中獲取一些數(shù)據(jù)。為了實(shí)現(xiàn)這些功能,需要使用服務(wù)、管理器,但是他們并不被認(rèn)為是VIPER架構(gòu)內(nèi)的模塊,而是外部依賴(lài).

  • 展示器(Presenter) -- 包含UI層面的業(yè)務(wù)邏輯以及在交互器層面的方法調(diào)用.

  • 實(shí)體(Entities) -- 普通的數(shù)據(jù)對(duì)象,不屬于數(shù)據(jù)訪(fǎng)問(wèn)層次,因?yàn)閿?shù)據(jù)訪(fǎng)問(wèn)屬于交互器的職責(zé).

  • 路由器(Router) -- 用來(lái)連接VIPER的各個(gè)模塊.

VIPER像樂(lè)高積木來(lái)搭建城堡,流程模式固定,如果項(xiàng)目比較大,那么VIPER是一把利刀.如果項(xiàng)目比較小,那么VIPER就優(yōu)點(diǎn)大材小用,而且會(huì)影響開(kāi)發(fā)的速度.

哲學(xué)家說(shuō)過(guò)存在即合理,每種架構(gòu)模式都有自己的適用場(chǎng)景,如果在項(xiàng)目中MVC能保持團(tuán)隊(duì)快速開(kāi)發(fā)也不一定非要切換到MVVM,架構(gòu)模式跟項(xiàng)目掌控者,公司的業(yè)務(wù)方向有很大關(guān)系.沒(méi)有絕對(duì)的正確,也沒(méi)有絕對(duì)的錯(cuò)誤.

參考鏈接:
iOS Architecture Patterns
被誤解的 MVC 和被神化的 MVVM

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容