在建筑學(xué)領(lǐng)域,有這樣一句話:我們雖然在營造建筑想许,但建筑也在重新塑造我們。作為一名開發(fā)人員断序,如果你曾認(rèn)真的去做過架構(gòu)相關(guān)的東西流纹,對這句話必然有著深刻體會。一個(gè)好的架構(gòu)违诗,不僅可以讓一款產(chǎn)品成功的投入使用漱凝,還可以讓產(chǎn)品具有良好的可維護(hù)性。這篇文章诸迟,主要介紹一種被稱為VIPER的架構(gòu)茸炒,并基于swift的特性去做相應(yīng)的設(shè)計(jì)。
VIPER是視圖(View)阵苇、交互器(Interactor)壁公、展示器(Presenter)器瘪、實(shí)體(Entity)和路由(Routing)的首字母縮寫池凄。
視圖:根據(jù)展示器的要求顯示界面,并將用戶輸入反饋給展示器打月;這里不僅僅是指UIView或其子類趁怔,還包括UIViewController湿硝,主要負(fù)責(zé)一些視圖的顯示、布局润努、用戶事件的接收关斜;
交互器:包含由用力指定的業(yè)務(wù)邏輯;
展示器:包含為顯示(從交互器接受的內(nèi)容)做的準(zhǔn)備工作的相關(guān)視圖邏輯铺浇,并對用戶輸入進(jìn)行反饋(從交互器獲取新數(shù)據(jù))痢畜;
實(shí)體:包含交互器要使用的基本模型對象;
路由:包含用來描述屏幕顯示和顯示順序的導(dǎo)航邏輯鳍侣;
這種分隔形式遵循單一責(zé)任原則丁稀。交互器負(fù)責(zé)業(yè)務(wù)分析的部分,展示器代表交互設(shè)計(jì)師倚聚,而視圖相當(dāng)于視覺設(shè)計(jì)師线衫。
在VIPER的實(shí)際應(yīng)用中,組件之間可以以任意順序來實(shí)現(xiàn)惑折,但在個(gè)人的實(shí)現(xiàn)過程中授账,經(jīng)過反復(fù)的理論推敲和實(shí)踐枯跑,推薦使用這樣的順序來進(jìn)行實(shí)現(xiàn)。
交互器
交互器的任務(wù)是根據(jù)業(yè)務(wù)邏輯來操縱模型對象(即實(shí)體)白热,它的工作應(yīng)當(dāng)獨(dú)立于任何用戶界面敛助,只對外暴露相應(yīng)的接口接口;同樣的交互器應(yīng)當(dāng)可以同時(shí)運(yùn)用于iOS應(yīng)用或 OS X應(yīng)用中屋确。交互器主要包含邏輯纳击,因此非常容易使用TDD進(jìn)行開發(fā)。故此乍恐,在實(shí)現(xiàn)交互器的時(shí)候评疗,只需要是一個(gè)普通的NSObject即可测砂,在其內(nèi)部處理對應(yīng)的業(yè)務(wù)邏輯茵烈,并向外提供簡明的交互接口。
實(shí)體
實(shí)體是被且僅被交互器操作的模型對象砌些,此處再次聲明交互器的作用:處理所有的業(yè)務(wù)邏輯呜投。在swift環(huán)境下,實(shí)體可以通過NSObject存璃、Struct來實(shí)現(xiàn)仑荐,如果使用了Core Data,最好將托管對象保持在數(shù)據(jù)層之后纵东。
展示器
在我實(shí)現(xiàn)VIPER的過程中粘招,展示器也是基于NSObject來實(shí)現(xiàn)的。展示器收集來自用戶的行為交互偎球,在合適的時(shí)候更新用戶界面并向交互器發(fā)送業(yè)務(wù)請求洒扎。在我們實(shí)現(xiàn)的過程中,展示器是整個(gè) VIPER 架構(gòu)的樞紐(也有人偏向于以 Interactor 為樞紐衰絮,通過具體實(shí)踐袍冷,個(gè)人推薦使用 Presenter),主要功能是各類消息的轉(zhuǎn)發(fā)和界面路由猫牡,如:Presenter 從 View 獲得用戶事件的消息胡诗,并發(fā)送給 Interactor ,Interactor 進(jìn)行相應(yīng)邏輯處理后淌友,反饋消息給 Presenter煌恢,Presenter 將消息再反饋到 View 上。
視圖
視圖一般處于一種被動接受的狀態(tài)震庭,被動接收來自用戶的行為交互瑰抵,被動接收由展示器傳遞來的消息(如展示器下發(fā)的需要展示的內(nèi)容)。展示器不知道視圖中存在的控件归薛,只負(fù)責(zé)告訴視圖在合適需要顯示什么樣的內(nèi)容谍憔,內(nèi)容如何顯示由視圖自行處理匪蝙。
路由
在實(shí)現(xiàn)路由的過程中,我嘗試過兩種方案习贫,一種是網(wǎng)上大多數(shù)VIPER架構(gòu)文章中介紹的wireframe(線框)逛球,另一種是基于URL的router。這兩種方案都實(shí)現(xiàn)以下兩個(gè)目的:
建立路由中間件苫昌,所有的界面跳轉(zhuǎn)由中間件處理颤绕;
所有界面跳轉(zhuǎn)可交由后臺控制,APP做好路由節(jié)點(diǎn)注冊祟身;
根據(jù)我們團(tuán)隊(duì)的實(shí)際情況和業(yè)務(wù)需求奥务,我們最終選擇使用基于URL的路由形式(命名為:GSRouter)。在此基礎(chǔ)上袜硫,參考了HandyJson的實(shí)現(xiàn)思想氯葬,我們?yōu)镚SRouter加入了參數(shù)自動解析功能,在此婉陷,對HandyJson的作者表示衷心的感謝帚称。
在實(shí)現(xiàn)路由模塊的過程中,不管是線框還是GSRouter秽澳,都是去注冊目標(biāo)vc的生成過程(以block的形式)闯睹。簡單來說就是,當(dāng)路由中間件發(fā)現(xiàn)你要跳轉(zhuǎn)到某個(gè)vc的時(shí)候担神,就去調(diào)用這個(gè)vc對應(yīng)的block楼吃,在block中初始化該vc,然后將初始化好的vc對象回調(diào)出來妄讯,再根據(jù)跳轉(zhuǎn)形式(present/dismiss or push/pop)進(jìn)行跳轉(zhuǎn)孩锡,同時(shí),還可以為跳轉(zhuǎn)配置對應(yīng)的動畫效果捞挥。當(dāng)然浮创,如果你使用的是storyboard,可以運(yùn)用建造者模式寫一個(gè)通用的vc對象生成方法(builder)砌函,不需要再經(jīng)過block斩披,然后為UIViewController添加一個(gè)參數(shù)自動解析方法,這樣你的路由模塊就已經(jīng)具有了基本的功能了讹俊。
以上是對VIPER的一個(gè)大致介紹垦沉,以及我個(gè)人在實(shí)現(xiàn)VIPER架構(gòu)過程中的一些感悟和理解,由于公司的保密要求仍劈,暫時(shí)未能提供小demo厕倍,在后面時(shí)間豐裕的時(shí)候,我會整理一個(gè)小demo并上傳到github贩疙,以供大家參考讹弯。如果上述表述中有任何不合適或理解不到位的地方况既,請大佬們批評指正。
最后组民,非常感謝您的耐心閱讀棒仍!