產(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)點
代碼量少:基于MVC上大量的邏輯和試圖代碼都集中在VC中,View和Model有嚴(yán)格區(qū)分,代碼分配遵循一定原則
簡單易懂:新手可以快速上手
缺點 —— 主要是視圖層和控制器層高度耦合造成的
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ù)雜。 缺點會被更加的放大。
小結(jié):MVC代碼分配過于籠統(tǒng),對于任何一個雷,主要不是View或Model就會放到vc中,VC類耦合了視圖和控制器。
MVCS
針對MVC的優(yōu)化;
S【store】【service】
一般存儲層(eg:CoreData)就是store;將它從Model或者vc中才分出來構(gòu)建單獨文件; 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是單獨的UIView/UIViewController, Presenter是單獨的類。

MVP中的View層是單獨的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)點:解耦View和Controller之間的耦合,將View和Presenter區(qū)分得更加清楚。將業(yè)務(wù)劃分更加精細(xì)
缺點: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持有模型,在更新模型上與前兩者相同,它完全獨立于視圖,視圖層擁有中間層,通過綁定屬性自動進(jìn)行更新,全部操作由響應(yīng)式邏輯框架自動完成。
優(yōu)缺點
MVC的耦合度很高, 代碼分配最不合理, 維護(hù)和擴(kuò)展成本最高。 但是因為無需層級傳遞, 所以代碼總量最少, 適合初學(xué)者理解和應(yīng)用;
MVP和MVVM相似, 耦合度和代碼分配都比較合理, 比較容易實現(xiàn)搞測試覆蓋率。
MVP的缺點是視圖層需要將所有的交互傳遞給中間層, 且要手動實現(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)。
公共缺點:沒有涉及到頁面之間的跳轉(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的缺點在于, 它依然與MVX架構(gòu)一樣, 是一個視圖驅(qū)動的架構(gòu)。同時VIPER由于分工精確, 不同的層級之間交互的代碼很多, 總體代碼量很大, 不適宜用在小型App中。
本文由mdnice多平臺發(fā)布