概述:
就目前我們在程序開發(fā)中應(yīng)用的架構(gòu)模式來說告嘲,MV(X)系列的架構(gòu)模式相對來說會比較容易上手、能夠滿足當(dāng)前對架構(gòu)的需求华嘹,所以說MV(X)系列目前依舊是主流吧趣。當(dāng)然,VIPER耙厚、RAC等這些架構(gòu)也都是很優(yōu)秀的架構(gòu)模式强挫,不過上手會比較慢、響應(yīng)鏈比較隱晦出現(xiàn)問題比較難發(fā)現(xiàn)薛躬,因此這里對于其他的架構(gòu)模式不做贅述俯渤,有興趣的可以自己去了解。
1泛豪、為什么要注重架構(gòu)模式稠诲?
如果不關(guān)心、不考慮架構(gòu)的問題诡曙,那么總有一天臀叙,我們會在一個龐大的類中去做各種各樣復(fù)雜的事情。你會發(fā)現(xiàn)在這樣的情況下价卤,根本不可能在這個類中快速找到以及有效的修改任何bug劝萤。而且當(dāng)這樣一個類作為整體時,我們總是很難去抓住重點慎璧,并且很多細節(jié)可能都會被忽略掉床嫌。因此,我們在項目中可能會遇到以下類似的問題:
1胸私、UI厌处、數(shù)據(jù)、業(yè)務(wù)等所有內(nèi)容全部寫在了ViewController中
2岁疼、數(shù)據(jù)直接在ViewController中存儲阔涉、處理
3、UIView幾乎不做任何事,或者過多地方從外部訪問View瑰排,使View變化不可控
4贯要、Model僅僅是一個數(shù)據(jù)結(jié)構(gòu),甚至沒有所謂的Model層
5椭住、各個類之間相互引用崇渗、嵌套,結(jié)構(gòu)復(fù)雜且混亂極易出現(xiàn)引用沖突京郑,修改一處代碼甚至?xí)l(fā)多處潛在問題
6宅广、模塊、功能耦合嚴(yán)重傻挂,可拓展性差乘碑、甚至基本無法拓展、無法重用
7金拒、在功能開發(fā)兽肤、問題修改中,可能不得不重構(gòu)以前的代碼
8绪抛、單元測試覆蓋不了任何用例资铡,甚至已經(jīng)沒有了單元測試的概念、存在的意義
上面只是列舉了部分可能會出現(xiàn)的問題幢码,這些往往是我們項目開發(fā)中的一些痛點笤休。所以說,為了避免這些問題我們必須要注重程序的架構(gòu)症副。而一個比較理想的架構(gòu)模式是怎樣的呢店雅?我認為應(yīng)該具備以下幾個特性:
1、每個類有自己的具體職責(zé)(單一職責(zé)的原則)贞铣,任務(wù)能夠均衡的分配給具體的類
2闹啦、不同類間從屬、引用關(guān)系簡單明確辕坝,最小引用原則
3窍奋、功能易于組件化、可移植性強
4酱畅、易用性琳袄、低成本維護
2、常用的MV(X)系列架構(gòu)
我們常說的MV(X)系列架構(gòu)纺酸,就是MVC窖逗、MVP、MVVM餐蔬。而其中的MVP滑负、MVVM其實是從MVC演變而來的在张。它們之所以可以統(tǒng)稱為MV(X)系列,也是因為這幾種架構(gòu)大致將程序分為了以下三類:
1矮慕、Model:負責(zé)主要的網(wǎng)絡(luò)數(shù)據(jù)或本地操作數(shù)據(jù)的數(shù)據(jù)訪問層,
2啄骇、View:負責(zé)展示層痴鳄,在iOS中即可認為所以以UI開頭的類
3、Controller/Presenter/ViewModel:負責(zé)協(xié)調(diào)Model和View缸夹,根據(jù)用戶在View上的操作在Model中對數(shù)據(jù)做對應(yīng)的修改痪寻,同時將修改后的數(shù)據(jù)返回到View上
通過上面這樣的架構(gòu)分層,會給我們的項目帶來這些好處:
1虽惭、便于我們?nèi)ダ斫馑鼈冎g的關(guān)系橡类,代碼劃分更清晰
2、View芽唇、Model更加容易復(fù)用
3顾画、沒有了各種平級類之間的相互引用,類更加安全匆笤,且可以進行獨立的單元測試
而這三種架構(gòu)的發(fā)展歷程大致是這樣的:
一研侣、MVC
1、架構(gòu)總攬
MVC(即Model-View-Controller)是最經(jīng)典的一種設(shè)計模式炮捧,也是在早起蘋果推薦開發(fā)者使用的架構(gòu)模式庶诡。讓我們來看下面這張經(jīng)典的架構(gòu)圖
從這張圖中我們可以看出,Model和View間是完全隔離的咆课,相互間不能去通信末誓,這也使得這兩個模塊的職責(zé)更加的純粹、安全书蚪。Controller在中間充當(dāng)了協(xié)調(diào)的作用喇澡,綁定持有View、Model對象善炫,負責(zé)Model和View間的通信撩幽。
2、通信方式:
View和Model間進制通信箩艺。
View和Controller間的通信:
View接收到用戶的響應(yīng)事件時窜醉,需要將其傳遞給Controller,如圖中View上的action就是事件艺谆,而Controller上的target就是目標(biāo)靶子榨惰。也可以通過代理的方式實現(xiàn)。
而Controller的話直接調(diào)用View暴露的外部方法即可實現(xiàn)對View的通信静汤。
Model和Controller間的通信:
Model內(nèi)部數(shù)據(jù)的變化最終是需要表現(xiàn)在View上的琅催,而Model內(nèi)部做了什么工作Controller居凶、View是不知道的,我們唯一關(guān)心的是當(dāng)Model中的值發(fā)生改變時藤抡,View的顯示需要同步的改變侠碧。所以,我們可以聯(lián)想到OC中有一個機制可以達到我們的目的缠黍,那就是KVO弄兜。除了KVO外,像是通知瓷式、Block等方式也都可以替饿,Model數(shù)據(jù)處理完成后告知Controller,由Controller去調(diào)度處理結(jié)果數(shù)據(jù)贸典。
Model和Controller間通過通知视卢、KVO、Block等方式來進行通信廊驼,具體選擇那種方式根據(jù)具體場景來決定据过。View和Controller間一般通過Delegate的方式來通信。
3蔬充、優(yōu)缺點
目前來看的話蝶俱,MVC整個架構(gòu)模式還是比較簡單、容易上手的饥漫,而且也基本能夠解決上面我們所提出的問題榨呆、滿足我們的需求。
那么庸队,MVC既簡單容易上手积蜻,又結(jié)構(gòu)清晰,那直接用它不就好了彻消?那么事實是怎樣的呢竿拆?
由于Controller需要承擔(dān)起View和Model間的通信的任務(wù),所以不可避免的會充斥各種代理和數(shù)據(jù)傳遞相關(guān)的代碼宾尚,隨著我們業(yè)務(wù)的增多丙笋、頁面復(fù)雜度的提升,Controller最終也會越來越臃腫煌贴。MVC中Controller協(xié)調(diào)View和Model太多的膠水代碼御板,例如3層View,則必須通過三層的傳遞才能將事件傳遞到Controller中牛郑。
除此之外怠肋,在實際編碼過程中,我們可能還會遇到一些問題淹朋。
比如笙各,我們判斷網(wǎng)絡(luò)狀況的代碼寫在哪里钉答?寫在Model中么?實際上杈抢,一般的網(wǎng)絡(luò)請求的發(fā)起和接收我們都放到了Controller中数尿,所以為了方便,索性就也寫到了Controller中惶楼。
至于View應(yīng)該是獨立的模塊了吧砌创?但是實際上,View大多數(shù)都放到了Controller中鲫懒,因為方便么,會有多少人單獨寫個類來封裝View呢刽辙?
當(dāng)我們需要校驗用戶名窥岩、密碼等內(nèi)容時,這樣的代碼會放在哪里宰缤?有多少人會單獨封裝個工具類呢颂翼?基本上都是在Controller中封裝個方法來寫,有的甚至都不會去封裝個方法慨灭。
大部分情況下我們?yōu)榱藞D快朦乏、方便,甚至是對不同層級職責(zé)的沒有足夠的理解氧骤,這些因素都會引發(fā)各種問題呻疹,使寫代碼越來越難。各種代碼沒有寫在它應(yīng)該寫的地方筹陵,而不好的習(xí)慣必然就會是的Controller變得越來越臃腫刽锤。Controller成為了上帝類,什么都干朦佩,本來應(yīng)該是最簡單的架構(gòu)并思,但是最后變得令人難懂了。
那么照這么說的話MVC用不了了嗎语稠?也不是宋彼。在實際開發(fā)中我們可以建立中間層,去解決上述問題仙畦。
比如歹鱼,我會將Controller自身的View剝離出來單獨封裝一個類(作為頁面所有子View的父類),然后將所有的View的綁定等操作寫在封裝好的父類中嚼贡,這樣的話Controller就不會充斥大量的UI相關(guān)的代碼了鬓催,也算一定程度上給Controller減壓了。但是這種方法并不能從根本上解決Controller臃腫的問題先口。
綜上所述型奥,MVC雖然有瓶頸瞳收,但是也是有它的優(yōu)勢的。如果我們的項目結(jié)構(gòu)厢汹、或者說某個功能比較簡單螟深,追求快速開發(fā),那么MVC無疑是一個比較好的選擇烫葬。但若我們的項目結(jié)構(gòu)比較龐大界弧、業(yè)務(wù)復(fù)雜、頁面復(fù)雜度高搭综,那么我們就需要另尋出路了垢箕。
二、MVP
1兑巾、架構(gòu)總攬
MVP(即Model-View-Presenter)來自于MVC条获,其中的Presenter負責(zé)邏輯的處理。在MVC中View和Model間的交互是通過Controller來進行橋接蒋歌、協(xié)調(diào)的帅掘,而在MVP中它們間的通信是通過Presenter來進行的,所有交互都發(fā)生在Presenter內(nèi)部堂油,極大的分擔(dān)了Controller的壓力修档。
整體的模塊、架構(gòu)劃分如下圖所示:
在這種架構(gòu)里府框,V指的是ViewController和View吱窝,此架構(gòu)將MVC中的ViewController進行了拆分,視圖邏輯數(shù)據(jù)處理進行了分離成為了這里的P(即Presenter)寓免,Model的含義沒有變化癣诱。View持有Presenter,Presenter持有Model袜香,反之撕予,則不能。
2蜈首、通信方式:
View和Model不能通信实抡。
View和Presenter間的交互:
用戶通過View觸發(fā)事件,View/ViewController實際上持有Presenter對象欢策、或者說直接操作Presenter類吆寨,在Presenter內(nèi)部會進行業(yè)務(wù)、UI邏輯的處理踩寇,處理完后通過代理的方式去更新View啄清。
Model和Presenter間的交互:
Presenter實際持有Model,它處理完業(yè)務(wù)邏輯后直接調(diào)用Model進行數(shù)據(jù)處理俺孙,Model返回結(jié)果后通過通知辣卒、代理掷贾、KVO等方式將結(jié)果返還給Presenter,Presenter根據(jù)結(jié)果對View進行更新荣茫。
在這里想帅,我們需要注意,Presenter不能持有View啡莉,否則會產(chǎn)生耦合港准,架構(gòu)設(shè)計就沒有意義了。在Presenter內(nèi)部沒有和布局有關(guān)的代碼咧欣,但是卻負責(zé)更新View的數(shù)據(jù)和狀態(tài)浅缸。原本View和Controller是緊密耦合的,但是我們通過MVP的協(xié)調(diào)器Presenter卻并不會對ViewController的生命周期做任何改變魄咕。
那我們的View如何添加到Controller上呢疗杉?其實還和前面講的MVC一樣,將ViewController的View剝離出來封裝成一個類ParentView蚕礼,將所有的子View進行集成。
如此一來梢什,我們的整個架構(gòu)中奠蹬,ViewController、ParentView里的大量的UI邏輯嗡午、業(yè)務(wù)邏輯代碼都被均衡到了Presenter中囤躁,ViewController的壓力會減小很多,而且邏輯分層更加明確荔睹。
3狸演、MVP和MVC的關(guān)聯(lián)和區(qū)別:
兩者的關(guān)系:
MVP是MVC的變種
項目開發(fā)中,界面UI是容易變化的僻他,同樣的數(shù)據(jù)也可能有多種顯示方式宵距,而業(yè)務(wù)邏輯也是比較容易變化的,為了使應(yīng)用擁有比較大的彈性吨拗,我們需要將UI满哪、邏輯(包括UI邏輯、業(yè)務(wù)邏輯)和數(shù)據(jù)分離開劝篷,而MVP則是一個比較好的選擇
兩者的基本設(shè)計思路相同哨鸭,Model用來存儲、處理數(shù)據(jù)娇妓,Controller/Presenter來協(xié)調(diào)View和Model間的通信像鸡。View接收到事件,并傳遞到Controller/Presenter哈恰,在內(nèi)部進行邏輯處理只估。
兩者的區(qū)別:
MVP中定義了一個Presenter協(xié)調(diào)器志群,將UI邏輯、業(yè)務(wù)邏輯進行了剝離仅乓,架構(gòu)分層更加清晰赖舟,避免了臃腫的Controller。
MVP的優(yōu)勢:
架構(gòu)分層更加清晰夸楣,將UI邏輯和業(yè)務(wù)邏輯更好的進行了分離宾抓,任務(wù)更好的均攤。實現(xiàn)了各模塊的解藕
可以高效的使用Presenter豫喧,可用于多個視圖石洗,而不需要改變Presenter的邏輯
MVP的缺點:
相對MVC的話代碼量會更多。
會對開發(fā)速度有一定的影響紧显,因為必須做一些手動的數(shù)據(jù)和事件的綁定讲衫。
因為將View的一些邏輯放到了Presenter,所以兩者的交互會過于頻繁孵班。
三涉兽、MVVM
1、架構(gòu)總攬
MVVM(即Model-View-ViewModel)其實也是MVC的衍生物篙程,這種架構(gòu)下枷畏,將View、Controller看做了統(tǒng)一層級的View(相當(dāng)于是把Controller的一部分邏輯剝離了出來)虱饿,數(shù)據(jù)層的處理由Model負責(zé)拥诡,ViewModel則是充當(dāng)了一個UI適配器的角色,從Controller中剝離出來的UI相關(guān)的邏輯都放在了ViewModel中氮发,減輕了Controller的負擔(dān)渴肉。
整體的架構(gòu)分層、交互如下圖:
View:視圖的展示爽冕。包含UIView和UIViewController仇祭,View層可以持有ViewModel
ViewModel:視圖的適配器。暴露屬性并且與View元素的顯示內(nèi)容或狀態(tài)一一對應(yīng)颈畸。ViewModel層可以持有Model前塔,但是不能持有View層。
Model:數(shù)據(jù)模型或數(shù)據(jù)邏輯處理類承冰。數(shù)據(jù)模型很好理解华弓,就是我們從服務(wù)器拉下來的數(shù)據(jù),經(jīng)過解析后的模型困乒。而數(shù)據(jù)邏輯處理類寂屏,就是本地數(shù)據(jù)操作、或遠程數(shù)據(jù)處理等方法形成的數(shù)據(jù)管理類。Model不可以持有ViewModel層迁霎。
附加說明:
數(shù)據(jù)綁定:MVVM的核心吱抚。它的作用是在View和ViewModel之間進行數(shù)據(jù)的雙向綁定,如果沒有這一步考廉,則它和MVP差異不是很大秘豹。
Controller:C持有VM,VM持有M昌粤,V持有VM同時又依賴于C
Controller的職責(zé):
1)既绕、self.view作為所有視圖的容器
2)、管理自己的生命周期
3)涮坐、處理不同Controller間的跳轉(zhuǎn)
4)凄贩、實現(xiàn)自身容器的作用,
2袱讹、通信方式:
View和ViewModel:View層會持有ViewModel疲扎,它們之間進行了雙向數(shù)據(jù)綁定,View進行用戶交互產(chǎn)生事件后捷雕,ViewModel會進行對應(yīng)的業(yè)務(wù)下發(fā)椒丧。而當(dāng)ViewModel中的屬性發(fā)生變化后,View監(jiān)聽到了會自動更新UI
ViewModel和Model:ViewModel會持有Model救巷,進行操作下發(fā)給Model進行數(shù)據(jù)處理瓜挽,Model將結(jié)果返還給ViewModel。
從上圖中我們可以看到它的架構(gòu)分層是不是和MVP很像征绸?而且業(yè)務(wù)劃分也是類似的,只不過中間協(xié)調(diào)者的命名不同而已俄占?事實上管怠,兩者最大的區(qū)別就在于View-ViewModel間的交互,即雙向數(shù)據(jù)綁定缸榄。
什么是雙向數(shù)據(jù)綁定呢渤弛?
View和ViewModel間建立了連接,當(dāng)View變化時會自動更新ViewModel甚带;而ViewModel中的動作完成后她肯,會自動去更新View。
舉個例子鹰贵,在View收到了事件消息晴氨,View通過改變ViewModel暴露的屬性值,借助KVO碉输,ViewModel收到了View發(fā)送的消息籽前,進而去調(diào)度Model執(zhí)行數(shù)據(jù)處理,當(dāng)數(shù)據(jù)發(fā)生變化后,會發(fā)送消息枝哄,View收到消息后更新自身UI
3肄梨、雙向數(shù)據(jù)綁定
我們說到MVVM架構(gòu),通常就會想到RAC挠锥,響應(yīng)式編程众羡,這個框架能夠幫助我們更容易的實現(xiàn)雙向數(shù)據(jù)綁定。通過上面的例子蓖租,應(yīng)該對什么是響應(yīng)式編程有一個大概的印象了粱侣。
MVVM中,如何去實現(xiàn)雙向數(shù)據(jù)綁定呢菜秦?如何簡化代碼甜害?關(guān)于這一點,有很多優(yōu)秀的第三方庫去幫助我們實現(xiàn)這一步驟:
基于KVO的綁定庫:如RZDataBinding球昨、SwiftBond尔店、FBKVOController
完全的函數(shù)響應(yīng)式編程(不限于雙向數(shù)據(jù)綁定):如ReactiveCocoa、RxSwift或PromiseKit
如果不借助三方庫主慰,如何自己去實現(xiàn)雙向綁定呢嚣州?
方案一:KVO
ViewModel->View。在View中實現(xiàn)KVO共螺,監(jiān)聽ViewModel中的屬性该肴,當(dāng)ViewModel中的屬性變化時,會通知View進行UI的更新藐不。
View->ViewModel匀哄。因為View持有ViewModel,可以直接通過ViewModel暴露的方法進行更新雏蛮、操作涎嚼。
以上,我們通過KVO基本上實現(xiàn)了雙向綁定數(shù)據(jù)挑秉,但是通過KVO在實際開發(fā)中會存在以下問題:
每次都需要寫大量的注冊法梯、移除、監(jiān)聽的處理等犀概,代碼比較負責(zé)
如果沒有移除監(jiān)聽的話立哑,可能會直接導(dǎo)致Crash,用起來不夠方便
方案二(個人理解):Block姻灶、Delegate
它們兩個不需要像KVO那樣步驟復(fù)雜铛绰,只需要聲明、使用产喉,所以可以將其實現(xiàn)的表達方式進行簡化至耻,用類似于KVO的表達方式若皱,也可以實現(xiàn)類似雙向數(shù)據(jù)綁定的模式。
在View中初始化綁定ViewModel的Block尘颓、Delegate走触,并保留一個接口來監(jiān)聽ViewModel的通知,在ViewModel中屬性值變化的地方進行Block疤苹、Delegate的回調(diào)通知即可互广,不需要區(qū)分不同業(yè)務(wù),通過返回參數(shù)值的方式卧土,使View做不同的更新惫皱。
雖然我們也可以通過KVO、類KVO的方式實現(xiàn)雙向綁定尤莺,不過會稍顯復(fù)雜旅敷,如果大面積使用的話,建議要么自己去封裝颤霎、簡化綁定類媳谁,要么使用相關(guān)的三方框架來幫助我們實現(xiàn)綁定功能。
4友酱、MVVM和MVP的共同點:
都是將ViewController視作View
在View和Model間沒有直接的聯(lián)系
都是通過中間層來實現(xiàn)View和Model的交互
區(qū)別:
MVVM核心思想是雙向綁定晴音,View的變動,自動反映在ViewModel上缔杉,反之亦然
MVVM中的ViewModel和View沒有太多的交流
MVVM中View會承擔(dān)更多锤躁,因為需要通過 ViewModel 的設(shè)置綁定來更新狀態(tài),而MVP中的View只監(jiān)聽 Presenter 的事件但并不會對自己有什么更新或详。
在實際開發(fā)中必須把View 中的事件指向 Presenter 并且手動的來更新 View系羞,如果使用綁定的話,MVVM 代碼量將會小的多霸琴。
MVVM的優(yōu)點:
1椒振、低耦合。View可以獨立于Model的變化沈贝、修改,一個ViewModel可以綁定到不同的View上勋乾,當(dāng)View變化時Model可以不變宋下。
2、獨立開發(fā)辑莫。開發(fā)人員可以分別進行View学歧、ViewModel的開發(fā)
3、MVVM中的View要比MVP中的View承擔(dān)更多的任務(wù)各吨。因為前者通過VViewModel的設(shè)置綁定來更新狀態(tài)枝笨,而后者只監(jiān)聽Presenter的事件但并不會對自己有什么更新。
MVVM的缺點:
學(xué)習(xí)成本高
上手慢,開發(fā)速度慢
Debug困難(調(diào)用棧會比較復(fù)雜)
對于過大的項目横浑,數(shù)據(jù)綁定需要花費更多的內(nèi)存剔桨。
附:
關(guān)于MVVM架構(gòu)在編碼中,具體如何劃分UI層徙融、業(yè)務(wù)層洒缀、數(shù)據(jù)層?層級間如何通信欺冀?如何更加高效的代碼實現(xiàn)树绩?如何組件化實現(xiàn)復(fù)用?編碼中如何防止內(nèi)存泄漏隐轩?等等問題饺饭,都需要我們在實際編碼中嘗試、熟悉后才能慢慢體會出來职车,嚴(yán)格遵守不同架構(gòu)中的編碼要求瘫俊,才能更加優(yōu)雅的去寫代碼。
更加詳細的編碼規(guī)范提鸟、技巧等军援,參考MVVM中的Demo,診斷信息導(dǎo)出功能模塊的代碼實現(xiàn)則嚴(yán)格根據(jù)MVVM架構(gòu)進行實現(xiàn)
總結(jié):
1称勋、幾種架構(gòu)的總結(jié)胸哥、選擇:
就目前的應(yīng)用來看,MVVM無疑是主流架構(gòu)赡鲜,無論是美團空厌、騰訊系很多產(chǎn)品都在使用MVVM架構(gòu)。但是银酬,這并不是說MVC嘲更、MVP架構(gòu)被淘汰了,不能用了揩瞪。事實上赋朦,我們需要針對不同的業(yè)務(wù)場景去選擇不同的架構(gòu),沒有最好的架構(gòu)李破,只有更合適的架構(gòu)宠哄。像是MVVM的話,也并不是說直接照搬這種模式嗤攻,在很多情況下會根據(jù)自己的場景去做改變毛嫉,根據(jù)業(yè)務(wù)去調(diào)整,和MVP妇菱、MVC混用等等承粤。
MVC暴区、MVP、MVVM這三種架構(gòu)在學(xué)習(xí)成本辛臊、開發(fā)時間仙粱、代碼的復(fù)雜程度、Debug成本上是遞增的浪讳,但是在架構(gòu)邏輯復(fù)雜度缰盏、總體代碼量、可移植的難度是遞減的淹遵。
如果功能模塊相對比較簡單口猜、在架構(gòu)上不想投入太多精力,則選擇MVC更加合適透揣。若項目比較龐大济炎,業(yè)務(wù)邏輯復(fù)雜,對代碼可移植性(重用)要求比較高辐真,追求更加清晰的架構(gòu)模式须尚,則MVP、MVVM更加合適侍咱。如果我們需要進一步均攤各個架構(gòu)層級的任務(wù)耐床,進一步解藕,簡化不同層級間通信代碼楔脯,并且愿意在架構(gòu)上投入更多的精力撩轰,則MVVM無疑是更優(yōu)的選擇,而MVVM也是目前MV(X)系列中相對來說更加優(yōu)秀的架構(gòu)模式昧廷】吧總之,根據(jù)自己的實際需求木柬、應(yīng)用場景選擇合適的架構(gòu)皆串,沒有最好的架構(gòu),只有更合適的架構(gòu)眉枕。
2恶复、關(guān)于解藕、復(fù)用:
我們經(jīng)常在談復(fù)用速挑,但是怎么去理解谤牡、并在實際編碼過程中實現(xiàn)復(fù)用呢?拿View來舉例梗摇,在MVC中的View不應(yīng)該引用任何其他自定義類的頭文件拓哟,而在MVVM中則除了ViewModel外也不應(yīng)該引入其他自定義類的頭文件想许。只有如此伶授,才能保證View拿到其他環(huán)境下最大程度的可以使用断序,而不需要修改過多的代碼。
附言:
上述是從概念糜烹、例子去介紹了幾種架構(gòu)违诗,但是并不代表我們一定要嚴(yán)格去那樣做,我們需要根據(jù)自己的業(yè)務(wù)對架構(gòu)進行優(yōu)化疮蹦、完善诸迟。
具體如何做,還需要大家在寫代碼過程中進行揣摩愕乎、理解阵苇。