產(chǎn)生架構(gòu)的原因喊递?
1随闪、代碼均攤
將不同的代碼進(jìn)行分塊,然后簡歷聯(lián)系骚勘,低耦合铐伴、高內(nèi)聚;
原則上:
合理的App架構(gòu)應(yīng)該是合理分配每個類俏讹、結(jié)構(gòu)體当宴、方法、變量的存在都應(yīng)該遵循單一職責(zé)的原則
2藐石、便于測試
測試確保代碼質(zhì)量即供;
單元測試、性能測試于微、UI測試 對單個方法或界面進(jìn)行測試逗嫡。
合理解決了分配決定了各個測試能夠各司其職、不重復(fù)株依、不遺漏驱证,讓測試效率和覆蓋率達(dá)到最大。
3恋腕、具有易用性
確保App架構(gòu)也可以保證他們能快速學(xué)習(xí)并適應(yīng)抹锄。
常見的架構(gòu)有:MVC(MVCS)、MVP、MVVM伙单、VIPER ...
0x01 MVC [model-view-controller]
Model層:負(fù)責(zé)數(shù)據(jù)處理获高,包括網(wǎng)絡(luò)數(shù)據(jù)和持久化數(shù)據(jù)的獲取、加工等吻育;
View層:負(fù)責(zé)處理界面繪制念秧,展示數(shù)據(jù),并對用戶產(chǎn)生及哦啊胡反饋等布疼;
Controller: 負(fù)責(zé)處理業(yè)務(wù)邏輯等摊趾。
MVC分為主動模式
和被動模式
—— 根據(jù)Model來劃分
被動模式
:不會主動將它的變化通知給View進(jìn)行更新,而是由Controller更新View關(guān)于Model的變化游两; 而且只有Controller可以對Model進(jìn)行更新砾层;
主動模式
:Model的修改會通知View更新,利用觀察者模式:View為觀察者贱案,Model為被觀察者肛炮。 在Web端,傳統(tǒng)意義上的MVC是主動模式宝踪; 而在移動端铸董,對數(shù)據(jù)變化頻繁的場景,可以應(yīng)用MVC的主動模式肴沫。
優(yōu)點(diǎn)
代碼量少
:基于MVC上大量的邏輯和試圖代碼都集中在VC中,View和Model有嚴(yán)格區(qū)分蕴忆,代碼分配遵循一定原則
簡單易懂
:新手可以快速上手
缺點(diǎn) —— 主要是視圖層
和控制器層
高度耦合造成的
1颤芬、代碼過于集中
:VC兩部分高度耦合,它處理交互套鹅、視圖更新站蝠、布局、Model數(shù)據(jù)獲取卓鹿、修改菱魔、導(dǎo)航等幾乎所有的操作
2、難以進(jìn)行測試
:高度耦合吟孙,使得檢測為主的單元測試需要配合特定試圖才能夠進(jìn)行澜倦,讓測試難度增大
3、難以擴(kuò)展
:VC中添加性功能要格外小心杰妓,高耦合容易出錯藻治。 View和VC高度耦合,可能會改動很大的代碼
4巷挥、Model層過于簡單
:model層基本上只是定義幾個屬性桩卵,.m文件中基本上看不到代碼
5、網(wǎng)絡(luò)請求層無從安放
:網(wǎng)絡(luò)層如果放在model層, 其異步調(diào)用API請求會使得整個model層變得復(fù)雜雏节;放在“”VC中胜嗓, VC更加復(fù)雜。 缺點(diǎn)會被更加的放大钩乍。
小結(jié):MVC代碼分配過于籠統(tǒng)辞州,對于任何一個雷,主要不是View或Model就會放到vc中件蚕,VC類耦合了視圖和控制器孙技。
MVCS
針對MVC的優(yōu)化;
S【store】【service】
一般存儲層(eg:CoreData)就是store排作;將它從Model或者vc中才分出來構(gòu)建單獨(dú)文件牵啦; MVC的網(wǎng)絡(luò)可以放到S層,逼近網(wǎng)絡(luò)請求獲得數(shù)據(jù)妄痪,要進(jìn)行緩存和持久化處理哈雏,所以放在數(shù)據(jù)層中也比較合理。
拆分出來衫生,代碼更加均衡裳瘪,VC難以單元測試,通過數(shù)據(jù)層拆分了之后罪针,整體架構(gòu)的維護(hù)和擴(kuò)展也起到了促進(jìn)的作用彭羹。
0x01 MVP [model-view-presenter]
相比MVC, model功能一樣
MVC中的View和Controller耦合在View類中
MVP View是單獨(dú)的UIView/UIViewController, Presenter是單獨(dú)的類泪酱。
MVP中的View層是單獨(dú)的Class[UIView/UIViewController]派殷,它持有Presenter作為變量;
View接收到用戶交互信息時墓阀,它會調(diào)用Presenter進(jìn)行處理毡惜;
View層不包括任何業(yè)務(wù)邏輯代碼,它只會將交互給Presenter斯撮, 并從Presenter中接收結(jié)果來更新自己经伙。
View持有Presenter,所以Presenter中的View應(yīng)該聲明為weak或unowned勿锅,避免循環(huán)帕膜。
優(yōu)點(diǎn):解耦View和Controller之間的耦合,將View和Presenter區(qū)分得更加清楚粱甫。將業(yè)務(wù)劃分更加精細(xì)
缺點(diǎn):View所有的交互都傳給Presenter處理泳叠,一旦項目功能增加了,View的代碼和Presenter的代碼將會增加茶宵。 相比MVC在VC一個文件里面就解決危纫,MVC總代碼量會增加。App維護(hù)成本和文件會增大。
0x02 MVVM - [model-viewmodel-view]
ViewModel: 提供數(shù)據(jù)种蝶、交互響應(yīng)契耿, 替換presenter
ViewModel一般扮演兩個角色:
1)視圖層的真正數(shù)據(jù)提供者
一般視圖層展示的數(shù)據(jù)經(jīng)常是一個或多個模型的屬性組合。
eg: 微薄數(shù)據(jù)流界面螃征,可能一個微薄用戶模型有FirstName, LastName, status, post等多個屬性搪桂; ViewModel就會將這些數(shù)據(jù)整合在一起,使得視圖直接調(diào)用單個數(shù)據(jù)就能夠展示索要的效果盯滚。
2)視圖層的交互響應(yīng)者
所有用戶的及哦啊胡都會傳遞給ViewModel, ViewModel會一次更新視圖層需要的屬性踢械,同時相應(yīng)修改模型層的數(shù)據(jù),這里依靠的是屬性觀察
或響應(yīng)式架構(gòu)
; 這里是View和ViewModel關(guān)系魄藕,而MVC中的主動是View和Model的關(guān)系内列。
小結(jié):ViewModel代替Presenter,增加了數(shù)據(jù)綁定的功能背率。
MVX的這三種架構(gòu)的區(qū)別
M:Model模型層
V: View 視圖層
C/P/VM: 中間層 Controller话瞧, Presenter,ViewModel
1)模型層幾乎相同
三種架構(gòu)的魔心從理論上說都是數(shù)據(jù)來源寝姿,沒什么不同交排;
2)視圖層在理論上都設(shè)計為被動,但是實際上略有不同
MVC
:實際上饵筑,視圖層和中間層高度耦合埃篓,幾乎所有的操作都是統(tǒng)一由ViewController包辦;理論上根资,視圖層是淡村的UIView或UIViewController都许,只是負(fù)責(zé)UI的更新和交互,不涉及業(yè)務(wù)邏輯和模型更新嫂冻; —— 實際上,MVP和MVVM的視圖是實現(xiàn)了MVC理論期望塞椎,即為中間層嚴(yán)格分離桨仿。
MVP
:視圖層完全是被動的,單純地把交互和更新傳遞給中間層
MVVM
:視圖層并不是完全被動案狠, 它監(jiān)視中間層的變化服傍,一旦產(chǎn)生變化,則視圖層會響應(yīng)變化骂铁。
3) 中間層的設(shè)計是三種架構(gòu)的核心差異
邏輯上
:中間層的作用是連接視圖層和模型層吹零,用于處理交互、接受通知和完成數(shù)據(jù)更新拉庵;
MVC中間層Controller 持有視圖和模型灿椅,主要起到組裝和連接的作用;通過傳遞參數(shù)和實例變量直接完成所有操作
MVP中間層Presenter持有模型,在更新模型上與MVC中的Controller是一樣的茫蛹;但是它不用有視圖操刀,視圖擁有中間層;中間層的工作流:從視圖層接收交互傳遞更新模型婴洼;接受模型的通知骨坑,更新視圖。 全部操作必須手動書寫代碼完成柬采。
MVVM中間層View Model持有模型欢唾,在更新模型上與前兩者相同,它完全獨(dú)立于視圖粉捻,視圖層擁有中間層礁遣,通過綁定屬性自動進(jìn)行更新,全部操作由響應(yīng)式邏輯框架自動完成杀迹。
優(yōu)缺點(diǎn)
MVC的耦合度很高亡脸, 代碼分配最不合理, 維護(hù)和擴(kuò)展成本最高树酪。 但是因為無需層級傳遞浅碾, 所以代碼總量最少, 適合初學(xué)者理解和應(yīng)用续语;
MVP和MVVM相似垂谢, 耦合度和代碼分配都比較合理, 比較容易實現(xiàn)搞測試覆蓋率疮茄。
MVP的缺點(diǎn)是視圖層需要將所有的交互傳遞給中間層滥朱, 且要手動實現(xiàn)響應(yīng)和更新, 所以總代碼量遠(yuǎn)遠(yuǎn)超過MVVM力试。
MVVM 在響應(yīng)和更新上徙邻, 通過響應(yīng)式框架自動操作, 大大精簡了代碼量畸裳; 但是需要引入第三方響應(yīng)式框架缰犁, 同時, 因為屬性觀察環(huán)環(huán)相扣怖糊, 調(diào)用棧很大帅容, 所以Debug起來尤為痛苦;
三者都是以視圖為驅(qū)動的架構(gòu)伍伤;即為:以用戶交互和試圖更新為主要服務(wù)目標(biāo)并徘。
公共缺點(diǎn):沒有涉及到頁面之間的跳轉(zhuǎn) —— 路由的設(shè)計
0x04 VIPER之間的各組件是如何交互的
關(guān)鍵詞: 路由、interactor
五個組成部分:View扰魂、Interactor麦乞、Presenter蕴茴、Enity、Router
1)視圖層(View)
:與MVP路幸、MVVM視圖層類似荐开,它包含UI相關(guān)的一切操作;它接收用戶的交互信息但并不處理简肴,而是傳遞給展示層(Presenter)
2)展示層(Presenter)
:與MVP的presenter或MVVM的VM類似晃听,對于它更加類似MVVM還是MVP,取決于是否引入響應(yīng)式編程架構(gòu)砰识; Presenter 在這里只響應(yīng)并處理視圖層傳來的交互操作請求能扒,并不直接對數(shù)據(jù)源進(jìn)行修改,這個與MVX中間層最大的區(qū)別辫狼;若是需要修改數(shù)據(jù)初斑,展示層會向其持有的數(shù)據(jù)管理層(Interactor)發(fā)送請求, Interactor 會處理一切有關(guān)數(shù)據(jù)源的操作膨处。 此外他還有路由了路由層(Router)
3)路由層 (Router)
:專門負(fù)責(zé)界面跳轉(zhuǎn)和組件之間的切換见秤;當(dāng)App占用空間較小時候,Router負(fù)責(zé)頁面跳轉(zhuǎn)真椿; 當(dāng)APP占用空間較大的時候鹃答,不同的功能和業(yè)務(wù)會被拆分成不同的模塊和組件,Router的作用就是在不同組件之間進(jìn)行連接突硝。 這就是MVX架構(gòu)所忽略的部分测摔;
4)數(shù)據(jù)管理層(Interactor)
:專門負(fù)責(zé)處理數(shù)據(jù)源信息, 包括你網(wǎng)絡(luò)請求解恰、數(shù)據(jù)傳輸锋八、緩存、存儲护盈、生成實例等操作挟纱。 實際上, 之前中間層和模型層的一些邏輯被進(jìn)一步剝離至此腐宋, 整個架構(gòu)的邏輯也顯得更加清晰樊销。
5)型層(Entity)
:只擁有初始化方法和屬性相關(guān)set/get方法, 與之前的Model層大同小異脏款;
小結(jié)
:由于分工明確, VIPER 層在代碼分配裤园、測試覆蓋率上為所有架構(gòu)之冠撤师。而VIPER的缺點(diǎn)在于, 它依然與MVX架構(gòu)一樣拧揽, 是一個視圖驅(qū)動的架構(gòu)剃盾。同時VIPER由于分工精確腺占, 不同的層級之間交互的代碼很多, 總體代碼量很大痒谴, 不適宜用在小型App中衰伯。
本文由mdnice多平臺發(fā)布