原創(chuàng):知識(shí)探索型文章
創(chuàng)作不易,請(qǐng)珍惜,之后會(huì)持續(xù)更新,不斷完善
個(gè)人比較喜歡做筆記和寫總結(jié),畢竟好記性不如爛筆頭哈哈,這些文章記錄了我的IOS成長(zhǎng)歷程,希望能與大家一起進(jìn)步
溫馨提示:由于簡(jiǎn)書不支持目錄跳轉(zhuǎn),大家可通過(guò)command + F 輸入目錄標(biāo)題后迅速尋找到你所需要的內(nèi)容
目錄
- 一、簡(jiǎn)介
- 二、VIP Cycle
- 三、總結(jié)
- 參考資料
一、簡(jiǎn)介
iOS同學(xué)一定了解或使用過(guò)一些常用的iOS頁(yè)面架構(gòu)模式,比如MVC、MVVM、MVP,甚至是VIPER。當(dāng)MVC、MVVM、MVP對(duì)于某些復(fù)雜頁(yè)面不夠用、而你又討厭VIPER時(shí),不妨試試Clean Swift(VIP)這種架構(gòu)。本文將對(duì)此架構(gòu)的原理和實(shí)踐方式做一個(gè)詳細(xì)的說(shuō)明以幫助感興趣的同學(xué)快速入門。
Clean Swift(也稱作VIP) 最初是由 Raymond Law 在他的網(wǎng)站 clean-swift.com 上提出的。 其背后思想是在遵循 Uncle Bob 的Clean Architecture中的主要思想的同時(shí),解決龐大視圖控制器問(wèn)題。
在使用Clean Swift模式時(shí),我們可以將頁(yè)面或頁(yè)面上的某一模塊看作一個(gè)場(chǎng)景。理論上,每個(gè)場(chǎng)景由大約6個(gè)組件構(gòu)成:
-
View Controller(視圖控制器,包括xib或storyboard) -
Interactor(交互器) -
Presenter(展示器) Model-
Router(路由器??蛇x) -
Worker(工作器,可以看作helper??蛇x)
其中,視圖控制器(V)、交互器(I)和展示器(P)是 Clean Swift 的三個(gè)主要組件。 它們作為彼此的輸入和輸出,如下圖所示:

視圖控制器的輸出連接到交互器的輸入,交互器的輸出連接到展示器的輸入,展示器的輸出連接到視圖控制器的輸入。 這意味著控制流和數(shù)據(jù)流始終是單向的。這被稱為 VIP Cycle。
二、VIP Cycle
Clean Swift 架構(gòu)使用VIP Cycle來(lái)幫助你分離代碼邏輯。VIP Cycle由ViewController、Interactor和 Presenter組成。ViewController 負(fù)責(zé)顯示,Interactor 負(fù)責(zé)業(yè)務(wù)邏輯,Presenter 負(fù)責(zé)展示邏輯。
ViewController(視圖控制器)
ViewController是在 VIP Cycle 中第一個(gè)觸發(fā)動(dòng)作的類。它的作用如下:
- 定義一個(gè)場(chǎng)景并包含一個(gè)或多個(gè)視圖。
- 持有
Interactor和Router的實(shí)例。 - 將視圖中的動(dòng)作封裝成一個(gè)
Request請(qǐng)求傳遞給Interactor(輸出),并將Presenter觸發(fā)的動(dòng)作作為ViewController的輸入。
Interactor(交互器)
包含該場(chǎng)景所有的業(yè)務(wù)邏輯(這對(duì)編寫單元測(cè)試好處極大,因?yàn)闇y(cè)試 Interactor時(shí),該場(chǎng)景中所有的業(yè)務(wù)邏輯都經(jīng)過(guò)了測(cè)試)。
- 持有
Presenter的實(shí)例。 - 根據(jù)輸入(來(lái)自
ViewController的Request),指揮Worker進(jìn)行操作(比如從數(shù)據(jù)庫(kù)、網(wǎng)絡(luò)獲取數(shù)據(jù))。完成操作時(shí),將從Worker處獲取到的原始數(shù)據(jù)封裝成Response傳遞給Presenter。
注意:Interactor 不需要也不應(yīng)該導(dǎo)入UIKit。
Presenter(展示器)
接收到 Interactor 傳遞的 Response 后,Presenter 將原始數(shù)據(jù)轉(zhuǎn)換成用于顯示的 viewModel,然后將 viewModel 傳遞回 ViewController 以顯示給用戶。
保存對(duì) ViewController(輸出)的弱引用。
Worker(工作器)
當(dāng)所有的業(yè)務(wù)邏輯都位于 Interactor 中時(shí),可能會(huì)導(dǎo)致Interactor是一個(gè)非常大的類。 為了防止這種情況,一個(gè)Interactor 可以使用多個(gè) Worker。 Worker 是 Interactor 的助手,可以幫助接收數(shù)據(jù)。
-
Worker是處理不同底層操作的抽象,比如從網(wǎng)絡(luò)/數(shù)據(jù)庫(kù)獲取信息、上傳/下載照片、喜歡/關(guān)注用戶等。 - 應(yīng)遵循單一職責(zé)原則(一個(gè)
Interactor可能包含許多具有不同職責(zé)的Worker)。 -
Worker必須是通用的,這樣就可以被多個(gè)Interactor使用。
注:如果你使用第三方SDK,比如使用 AFNetworking 做網(wǎng)絡(luò)請(qǐng)求,而網(wǎng)絡(luò)請(qǐng)求是在Worker里面做的,那么只需在 Worker 中引入AFNetworking。
Router(路由器)
有可能存在當(dāng)前場(chǎng)景的 ViewController 將展示另一個(gè) ViewController 的情況。 在 Clean Swift中,ViewController 之間的導(dǎo)航是由 Router 完成的。
當(dāng)屏幕或場(chǎng)景發(fā)生轉(zhuǎn)換時(shí),ViewController 需要向Interactor發(fā)起Request,然后 Interactor 需要向Presenter 進(jìn)行詢問(wèn),最終由 Presenter 來(lái)決定 ViewController 可以使用 Router 路由到哪一個(gè) ViewController。
-
Router從ViewController中提取所有的導(dǎo)航邏輯,這使得ViewController具有哪些導(dǎo)航選項(xiàng)變得一目了然。 - 保存對(duì)源
ViewController的弱引用。
Model
在 VIP Cycle 中,每個(gè)類在向該循環(huán)中的其他類進(jìn)行請(qǐng)求動(dòng)作時(shí)都會(huì)創(chuàng)建一個(gè)數(shù)據(jù)對(duì)象。 這樣做的目的是解耦各個(gè)類。
- 當(dāng)
ViewController向Interactor請(qǐng)求一個(gè)動(dòng)作時(shí),ViewController將添加一個(gè)“請(qǐng)求”對(duì)象(Request)。 該對(duì)象包含Interactor在執(zhí)行業(yè)務(wù)邏輯時(shí)需要的所有數(shù)據(jù)。 -
Interactor將處理來(lái)自ViewController的請(qǐng)求。 處理完成后,它將向Presenter返回一個(gè)“響應(yīng)”對(duì)象(Response)。 -
Presenter將解析來(lái)自Interactor的 原始數(shù)據(jù),提取/轉(zhuǎn)換用于顯示的數(shù)據(jù)并封裝為 “ViewModel”對(duì)象,該對(duì)象將被發(fā)送到ViewController。 - 當(dāng)
ViewController接收到ViewModel時(shí),ViewController只需要使用ViewModel中的數(shù)據(jù)更新 UI即可。
三、總結(jié)
完整模式
ViewController 在初始化完成后,在內(nèi)部創(chuàng)建 Interactor、Presenter、Router實(shí)例,ViewController僅保存Interactor 和 Router 實(shí)例,將 Presenter 實(shí)例傳遞給 Interactor 來(lái)保存,并將ViewController作為弱引用傳遞給 Presenter 和 Router(防止循環(huán)引用)。

優(yōu)點(diǎn)
- 易于維護(hù)、擴(kuò)展和
bug fix。因?yàn)槟憧梢源_切地知道哪個(gè)邏輯位于哪個(gè)類中。 - 很好地執(zhí)行了單一職責(zé)原則。
- 很好地使用
Worker構(gòu)建可重用的組件。 - 由于使用協(xié)議來(lái)進(jìn)行類之間的解耦,因此當(dāng)需要替換一個(gè)類時(shí),只需要讓新的類遵從某個(gè)協(xié)議,而無(wú)需修改其他類的代碼。
- 方便進(jìn)行單元測(cè)試,并容易達(dá)到很高的代碼覆蓋率。
缺點(diǎn)
- 許多協(xié)議的命名和職責(zé)復(fù)雜,起初可能會(huì)混淆協(xié)議在哪里定義。
- 很難保持
ViewController和Presenter之間的完全分離。因?yàn)橛袝r(shí)Presenter只是調(diào)用ViewController的方法而不是準(zhǔn)備UI顯示用的數(shù)據(jù),因此它看起來(lái)沒(méi)用,只是為了要遵守樣板代碼而不得不這樣做。
總結(jié)
-
Clean Swift不是最容易維護(hù)的,但可能是避免耦合并能夠保持高代碼覆蓋率的最佳方法。 -
VIP Cycle使用中等數(shù)量的樣板代碼強(qiáng)制執(zhí)行嚴(yán)格的命名約定和類職責(zé)。