不論是前端,后臺(tái),移動(dòng)端,結(jié)合到現(xiàn)實(shí)生活中,處處都會(huì)涉及到框架的應(yīng)用,一個(gè)初期就設(shè)計(jì)優(yōu)良的架構(gòu),素容置疑在項(xiàng)目的可維護(hù)性,擴(kuò)展性,健壯性肯定都有很大的提升。所以我們必須要在開(kāi)發(fā)之前在架構(gòu)上面多下功夫!
對(duì)于一個(gè)項(xiàng)目來(lái)說(shuō) 架構(gòu) 一直是個(gè)值得關(guān)注的大話題, 這里我將其劃分為幾個(gè)部分去思考,設(shè)計(jì)。
文件目錄模塊架構(gòu), Coding設(shè)計(jì)模式層面架構(gòu) , 網(wǎng)絡(luò)層框架架構(gòu), 數(shù)據(jù)持久化架構(gòu), UIKit層面架構(gòu),暫時(shí)先以這幾個(gè)重要的層面去考慮,和設(shè)計(jì)。我們來(lái)依次討論這幾個(gè)模塊的理解和設(shè)計(jì)方案。
文件目錄模塊架構(gòu)
對(duì)于一個(gè)項(xiàng)目來(lái)說(shuō),最直觀的設(shè)計(jì)就是在文件目錄結(jié)構(gòu)上,一個(gè)好的文件目錄結(jié)構(gòu)劃分能讓我們自己在開(kāi)發(fā)過(guò)程中更加快速編寫代碼,也能讓新加入的同事更快速的融入到項(xiàng)目中來(lái),你想一下如果文件目錄劃分清晰明了,和一個(gè)雜亂無(wú)章的目錄結(jié)構(gòu),那個(gè)閱讀起來(lái)舒服?其就像一本書的編寫排版,讀完排序之后讀者基本讀整本書內(nèi)容有一個(gè)清晰的認(rèn)識(shí),以及在后面閱讀起來(lái)隨時(shí)能通過(guò)排序來(lái)找到相應(yīng)的章節(jié).
所以在開(kāi)發(fā)前期我們都應(yīng)該根據(jù)我們當(dāng)前項(xiàng)目所有涉及到的業(yè)務(wù)場(chǎng)景,需要使用到的模塊心里都要有一個(gè)準(zhǔn)備,參考了一些開(kāi)源項(xiàng)目,以及網(wǎng)上關(guān)于項(xiàng)目目錄劃分的文章, 主流的劃分邏輯大概是分為兩種.
按項(xiàng)目?jī)?nèi)每個(gè)大的模塊功能來(lái)進(jìn)行文件夾劃分.
按主要的設(shè)計(jì)模式來(lái)進(jìn)行劃分,例如: ViewController. View.Model VS ViewModel等.
個(gè)人更傾向于第一種, 舉個(gè)栗子. 以********支付寶********為例,項(xiàng)目 TabBar 分為 5 個(gè)大模塊, 一個(gè)是首頁(yè),財(cái)富,口碑,朋友,我的. 然后在依次建立 5 個(gè)相應(yīng)的文件夾,當(dāng)然還會(huì)有一些涉及功能很多的模塊,比如項(xiàng)目里面的商城,生活號(hào),小程序等,雖然可能都包含在這 5 個(gè)大的模塊里面, 我們可以根據(jù)實(shí)際場(chǎng)景結(jié)合業(yè)務(wù), 如果某個(gè)模塊業(yè)務(wù)涉及場(chǎng)景和業(yè)務(wù)比較復(fù)雜, 都可以單獨(dú)為其建立一個(gè)獨(dú)立的文件夾, 與其他 5 個(gè)模塊進(jìn)行平級(jí)別的劃分。
除了對(duì)模塊進(jìn)行劃分外,我們?cè)趯?duì)項(xiàng)目里面肯定都會(huì)包含的網(wǎng)絡(luò)層,數(shù)據(jù)持久層,工具類庫(kù)層,三方資源層等等...這些在項(xiàng)目中使用率高的核心層面,也單獨(dú)劃分成一個(gè)文件夾的形式,方便以后新增代碼的時(shí)候,將其按功能點(diǎn)來(lái)添加和劃分。
這樣我們開(kāi)發(fā)過(guò)程中查找相應(yīng)類文件,新增的時(shí)候也不會(huì)浪費(fèi)太多的時(shí)間,也方便其他人閱讀。
設(shè)計(jì)模式層面架構(gòu)
這里主要是涉及到 設(shè)計(jì)模式的選擇上, 目前比較主流的有 MVC.MVVM.MVP。然后我參考了知名應(yīng)用 小猿搜題庫(kù) 出的設(shè)計(jì)模式架構(gòu)篇, 其主要是圍繞 MVC 和 MVVM 將其優(yōu)缺點(diǎn)進(jìn)行一個(gè)優(yōu)良改造版. 在兩種架構(gòu)中權(quán)衡而產(chǎn)生的架構(gòu)MVVM without Binding with DataController, 我覺(jué)得很值得大家去參考,學(xué)習(xí).
關(guān)于在設(shè)計(jì)模式上, 我覺(jué)得還是應(yīng)該結(jié)合自己實(shí)際業(yè)務(wù)場(chǎng)景去進(jìn)行選擇最好, 不需要太死板要求為了遵守這種設(shè)計(jì)模式而遵守。每一種設(shè)計(jì)都有其優(yōu)缺點(diǎn), 我們應(yīng)該權(quán)衡其利與弊抱著學(xué)習(xí)的態(tài)度來(lái)對(duì)待, 只要其能真正解決我們的痛點(diǎn)就是一個(gè)好的設(shè)計(jì)模式, 在選擇上面我比較傾向于項(xiàng)目中多種設(shè)計(jì)模式公用的做法。 具體根據(jù)當(dāng)前業(yè)務(wù)場(chǎng)景來(lái)。
網(wǎng)絡(luò)框架架構(gòu)
為什么要對(duì)網(wǎng)絡(luò)層進(jìn)行封裝. 網(wǎng)絡(luò)層的代碼幾乎遍布我們每一個(gè)頁(yè)面, 想象一下假如我們不對(duì)網(wǎng)絡(luò)層進(jìn)行一個(gè)良好的封裝, 每次調(diào)用原生庫(kù) NSURLSession 來(lái)請(qǐng)求一段網(wǎng)絡(luò)大家會(huì)是什么心情? 在想象一個(gè)每次我們請(qǐng)求網(wǎng)絡(luò)的時(shí)候基本都會(huì)添加一些公共參數(shù),緩存處理,統(tǒng)一錯(cuò)誤碼等處理吧, 還有請(qǐng)求返回格式化設(shè)置等等. 這些都是基本很少變動(dòng)的配置, 我們對(duì)其都做好封裝,上層直接傳入請(qǐng)求方法,URL,進(jìn)來(lái)即可.
上面說(shuō)的比較淺, 相信大家在項(xiàng)目中對(duì)網(wǎng)絡(luò)層封裝至少都 2 層以上, 本人主要是對(duì) AFNetWorking 進(jìn)行的一個(gè)封裝, 第一層封裝主要對(duì) AFHttpSeesionManage 的初始化設(shè)置以及安全策略,證書校驗(yàn),還有請(qǐng)求超時(shí)處理等. 第二層則是直接獲取網(wǎng)絡(luò)的類,對(duì)其做了一些添加公共參數(shù),處理返回?cái)?shù)據(jù)公共邏輯,返回結(jié)果錯(cuò)誤碼,添加緩存,緩存處理等。
這樣做的好處有幾點(diǎn).
1. 假如有一天 AFNetWorking 不更新維護(hù)了, Apple 棄用了其最新版本的基于 NSURLSession 的網(wǎng)絡(luò)請(qǐng)求類, 我們可能需要考慮更換一個(gè)新的底層網(wǎng)絡(luò)庫(kù). 我們只需要更改第一層封裝庫(kù)的代碼即可。 大大降低了對(duì)三方庫(kù)的依賴關(guān)系
2. 通過(guò)第一層封裝不僅完成了 降低依賴關(guān)系, 我們還做了公共的配置, 方便后續(xù)在做網(wǎng)絡(luò)請(qǐng)求時(shí), 不需要再重新配置, 實(shí)現(xiàn)只配置一次即可共全局使用的效果。 類似的第二層添加公共參數(shù)也是如此。
3. 第二層封裝主要是我們?cè)趯?shí)際業(yè)務(wù)場(chǎng)景中,基本每個(gè)網(wǎng)絡(luò)請(qǐng)求都會(huì)攜帶一些公共參數(shù), 比如當(dāng)前項(xiàng)目版本號(hào),設(shè)備號(hào),時(shí)間等,后臺(tái)要求每次請(qǐng)求都要攜帶上這些公共參數(shù), 我們將其封裝起來(lái)。
4. 處理請(qǐng)求結(jié)果錯(cuò)誤碼,基本同理。
總結(jié):不寫重復(fù)的代碼。
數(shù)據(jù)持久化架構(gòu)
由于項(xiàng)目是主打 IM 即時(shí)通訊的, 會(huì)涉及到很多數(shù)據(jù)都需要保存到本地, 以及讀取緩存的操作, 所以后期肯定要在數(shù)據(jù)緩存處理,數(shù)據(jù)讀取,數(shù)據(jù)存儲(chǔ)上做精心設(shè)計(jì). 這一塊目前自己能力有限, 主要我們先參考大神文章為主. 留個(gè)坑, 后續(xù)我們?cè)趤?lái)補(bǔ)上, 希望有數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì),緩存處理方案的大神能指一二。
UIKit層面架構(gòu)
UIKit 層面涉及到的范圍也比較廣, 我主要從視圖控制器下手進(jìn)行封裝, 采用 BaseViewController 的方式, 對(duì) ViewController 和 UINavigationController 以及 UITabBarController 等進(jìn)行一個(gè) 基類控制器的封裝, 將一些統(tǒng)一的參數(shù),業(yè)務(wù)等進(jìn)行配置, 方便后續(xù)在項(xiàng)目中類似的控制器中, 直接通過(guò)集成 BaseViewController 就可以輕松實(shí)現(xiàn)的功能.
結(jié)語(yǔ)
作者水平有限,文中可能有說(shuō)的不對(duì),或者錯(cuò)誤的地方歡迎大家指正。
主要是通過(guò)參考網(wǎng)上比較出名的文章,結(jié)合自己項(xiàng)目實(shí)際場(chǎng)景來(lái)進(jìn)行,后續(xù)我會(huì)把自己看到的相關(guān)資料統(tǒng)統(tǒng)放下面供大家參考! 非常感謝這些大神,前輩為我們提供如此精辟的技術(shù)分享,如同一盞黑暗里的明燈,不斷指引我們走向光明大道!
參考資料:
iOS應(yīng)用架構(gòu)談 view層的組織和調(diào)用方案
猿題庫(kù) iOS 客戶端架構(gòu)設(shè)計(jì)
淺析 iOS 應(yīng)用網(wǎng)絡(luò)層設(shè)計(jì)
iOS應(yīng)用架構(gòu)談 網(wǎng)絡(luò)層設(shè)計(jì)方案
onmyway133/fantastic-ios-architecture 設(shè)計(jì)模式架構(gòu)思想?yún)R總
老碼農(nóng)冒死揭開(kāi)行業(yè)黑幕:如何編寫無(wú)法維護(hù)的代碼
優(yōu)秀的 iOS 應(yīng)用架構(gòu):MVVM、MVC、VIPER,孰優(yōu)孰劣