版本記錄
版本號(hào) | 時(shí)間 |
---|---|
V1.0 | 2018.05.16 |
前言
前面寫了那么多篇主要著眼于局部問題的解決,包括特定功能的實(shí)現(xiàn)蚯姆、通用工具類的封裝硫麻、視頻和語音多媒體的底層和實(shí)現(xiàn)以及動(dòng)畫酷炫的實(shí)現(xiàn)方式等等。接下來這幾篇我們就一起看一下關(guān)于iOS系統(tǒng)架構(gòu)以及獨(dú)立做一個(gè)APP的架構(gòu)設(shè)計(jì)的相關(guān)問題官硝。感興趣的可以看上面幾篇矗蕊。
1. 架構(gòu)之路 (一) —— iOS原生系統(tǒng)架構(gòu)(一)
回顧
上一篇主要講述了蘋果原生iOS框架的架構(gòu),這一篇我們就說一下如果自己要完成一個(gè)APP氢架,需要如何去設(shè)計(jì)架構(gòu)傻咖。
架構(gòu)設(shè)計(jì)結(jié)構(gòu)上劃分
我們說APP的架構(gòu)設(shè)計(jì),但是架構(gòu)設(shè)計(jì)需要我們怎么在結(jié)構(gòu)上進(jìn)行劃分呢岖研?可以按照下面進(jìn)行劃分卿操。
-
網(wǎng)絡(luò)設(shè)計(jì)方案
- 這里包括對(duì)網(wǎng)絡(luò)層很好的設(shè)計(jì)和封裝,讓工程師可以方便安全的調(diào)用,同時(shí)也要保證用戶在各種網(wǎng)絡(luò)環(huán)境下有很好的體驗(yàn)硬纤。
-
數(shù)據(jù)解析和頁面渲染設(shè)計(jì)方案
- 這里包括數(shù)據(jù)模型的搭建解滓、頁面如何封裝降低耦合以及高效的渲染。
-
數(shù)據(jù)持久化存儲(chǔ)設(shè)計(jì)方案
- 這里包括筝家,當(dāng)有本地存儲(chǔ)的需求時(shí)洼裤,如何保證數(shù)據(jù)可以在本地合理的存儲(chǔ)。
-
動(dòng)態(tài)部署方案
- 這里包括溪王,如何不發(fā)版就更新版本和解決問題腮鞍。這個(gè)以前都用熱更新hotfix,不需要發(fā)版就可以進(jìn)行更新莹菱,但是蘋果現(xiàn)在給禁掉了∫乒現(xiàn)在還有一個(gè)可以解決部分問題的方案:可以采用云控,利用服務(wù)端進(jìn)行控制道伟,達(dá)到對(duì)某些功能的調(diào)控迹缀,但是還是不能通過熱更新進(jìn)行更新版本。
其實(shí)也可以有三層分層架構(gòu):展現(xiàn)層蜜徽、業(yè)務(wù)層祝懂、數(shù)據(jù)層。
- 展現(xiàn)層:視圖頁面渲染
- 業(yè)務(wù)層:業(yè)務(wù)功能實(shí)現(xiàn)
- 數(shù)據(jù)層:包括數(shù)據(jù)的下載(包含所謂的網(wǎng)絡(luò)層)和轉(zhuǎn)化拘鞋,甚至持久化
好的架構(gòu)衡量標(biāo)準(zhǔn)
-
代碼整齊砚蓬,分類明確
- 代碼整齊是每一個(gè)工程師的基本素質(zhì),先不說你搞定這個(gè)問題的方案有多好盆色,解決速度有多快灰蛙,如果代碼不整齊,一切都白搭隔躲。分類明確的字面意思大家一定都了解摩梧,但還有一個(gè)另外的意思,那就是:不要讓一個(gè)類或者一個(gè)模塊做兩種不同的事情宣旱。如果有類或某模塊做了兩種不同的事情仅父,一方面不適合未來拓展,另一方面也會(huì)造成分類困難响鹃。
-
不用文檔驾霜,或很少文檔案训,就能讓業(yè)務(wù)方上手
- 盡可能讓你的API名字可讀性強(qiáng)买置,對(duì)于iOS來說,objc這門語言的特性把這個(gè)做到了極致强霎,函數(shù)名長就長一點(diǎn)忿项,不要緊。
-
思路和方法要統(tǒng)一,盡量不要多元
- 解決一個(gè)問題會(huì)有很多種方案轩触,但是一旦確定了一種方案寞酿,就不要在另一個(gè)地方采用別的方案了。也就是做架構(gòu)的時(shí)候脱柱,你得時(shí)刻記住當(dāng)初你決定要處理這樣類型的問題的方案是什么伐弹,以及你的初衷是什么,不要搖擺不定榨为。另外惨好,你當(dāng)初設(shè)立這個(gè)模塊一定是有想法有原因的,要記錄下你的解決思路随闺,不要到時(shí)候換個(gè)地方你又靈光一現(xiàn)啥的日川,引入了其他方案,從而導(dǎo)致異構(gòu)矩乐。
-
沒有橫向依賴龄句,萬不得已不出現(xiàn)跨層訪問
- 沒有橫向依賴是很重要的,這決定了你將來要對(duì)這個(gè)架構(gòu)做修補(bǔ)所需要的成本有多大散罕。要做到?jīng)]有橫向依賴分歇,這是很考驗(yàn)架構(gòu)師的模塊分類能力和是否熟悉業(yè)務(wù)的”渴梗跨層訪問是指數(shù)據(jù)流向了跟自己沒有對(duì)接關(guān)系的模塊卿樱。有的時(shí)候跨層訪問是不可避免的,比如網(wǎng)絡(luò)底層里面信號(hào)從2G變成了3G變成了4G硫椰,這是有可能需要跨層通知到View的繁调。但這種情況不多,一旦出現(xiàn)就要想盡一切辦法在本層搞定或者交給上層或者下層搞定靶草,盡量不要出現(xiàn)跨層的情況蹄胰。跨層訪問同樣也會(huì)增加耦合度奕翔,當(dāng)某一層需要整體替換的時(shí)候裕寨,牽涉面就會(huì)很大。
-
對(duì)業(yè)務(wù)方該限制的地方有限制派继,該靈活的地方要給業(yè)務(wù)方創(chuàng)造靈活實(shí)現(xiàn)的條件
- 把這點(diǎn)做好宾袜,很依賴于架構(gòu)師的經(jīng)驗(yàn)。架構(gòu)師必須要有能力區(qū)分哪些情況需要限制靈活性驾窟,哪些情況需要?jiǎng)?chuàng)造靈活性庆猫。比如對(duì)于Core Data技術(shù)棧來說,
ManagedObject
理論上是可以出現(xiàn)在任何地方的绅络,那就意味著任何地方都可以修改ManagedObject月培,這就導(dǎo)致ManagedObjectContext在同步修改的時(shí)候把各種不同來源的修改同步進(jìn)去嘁字。這時(shí)候就需要限制靈活性,只對(duì)外公開一個(gè)修改接口杉畜,不暴露任何ManagedObject在外面纪蜒。如果是設(shè)計(jì)一個(gè)ABTest相關(guān)的API的時(shí)候,我們又希望增加它的靈活性此叠。使得業(yè)務(wù)方不光可以通過Target-Action的模式實(shí)現(xiàn)ABtest纯续,也要可以通過Block的方式實(shí)現(xiàn)ABTest,要盡可能滿足靈活性灭袁,減少業(yè)務(wù)方的使用成本杆烁。
- 把這點(diǎn)做好宾袜,很依賴于架構(gòu)師的經(jīng)驗(yàn)。架構(gòu)師必須要有能力區(qū)分哪些情況需要限制靈活性驾窟,哪些情況需要?jiǎng)?chuàng)造靈活性庆猫。比如對(duì)于Core Data技術(shù)棧來說,
-
易測試,易拓展
- 要實(shí)現(xiàn)易測試易拓展简卧,那就要提高模塊化程度兔魂,盡可能減少依賴關(guān)系。如果是高度模塊化的架構(gòu)举娩,拓展起來將會(huì)是一件非常容易的事情析校。
-
保持一定量的超前性
- 這一點(diǎn)能看出架構(gòu)師是否關(guān)注行業(yè)動(dòng)態(tài),是否能準(zhǔn)確把握技術(shù)走向铜涉。保持適度的技術(shù)上的超前性智玻,能夠使得你的架構(gòu)更新變得相對(duì)輕松。另外芙代,這里的超前性也不光是技術(shù)上的吊奢,還有產(chǎn)品上的。
-
接口少纹烹,接口參數(shù)少
- 越少的接口越少的參數(shù)页滚,就能越降低業(yè)務(wù)方的使用成本。
-
高性能
- 高性能非常重要铺呵,但是在客戶端架構(gòu)中裹驰,它不是第一考慮因素∑遥客戶端業(yè)務(wù)變化非常之快幻林,做架構(gòu)時(shí)首要考慮因素應(yīng)當(dāng)是便于業(yè)務(wù)方快速滿足產(chǎn)品需求,因此需要盡可能提供簡單易用效果好的接口給業(yè)務(wù)方音念,而不是提供高性能的接口給業(yè)務(wù)方沪饺。
架構(gòu)模式的選擇
前面根據(jù)需求對(duì)框架的架構(gòu)分類,可以分為三層結(jié)構(gòu)甚至四層結(jié)構(gòu)闷愤,這里就說一下架構(gòu)模式整葡,可以說架構(gòu)模式是架構(gòu)實(shí)現(xiàn)的方式。常見的有MVC肝谭、MVVM和VOPER等掘宪。好的架構(gòu)模式可以讓模塊功能更清晰,維護(hù)起來也很方便攘烛。
下面就一起看一下這幾種架構(gòu)模式:
1. MVC
- 任務(wù)均攤 – View和Model確實(shí)是分開的魏滚,但是View和Controller卻是緊密耦合的
- 可測試性 – 由于糟糕的分散性,只能對(duì)Model進(jìn)行測試
- 易用性 – 與其他幾種模式相比最小的代碼量坟漱。熟悉的人很多鼠次,因而即使對(duì)于經(jīng)驗(yàn)不那么豐富的開發(fā)者來講維護(hù)起來也較為容易。
這里MVC就不多說了芋齿,相信大家對(duì)它是最先接觸也是最熟悉的了腥寇。
2. MVVM
- 任務(wù)均攤 – 事實(shí)上样傍,MVVM的View要比MVP中的View承擔(dān)的責(zé)任多锋爪。因?yàn)榍罢咄ㄟ^ViewModel的設(shè)置綁定來更新狀態(tài)璧针,而后者只監(jiān)聽Presenter的事件但并不會(huì)對(duì)自己有什么更新巷蚪。
- 可測試性 – ViewModel不知道關(guān)于View的任何事情初狰,這允許我們可以輕易的測試ViewModel广鳍。同時(shí)View也可以被測試惶翻,但是由于屬于UIKit的范疇杨箭,對(duì)他們的測試通常會(huì)被忽略赢赊。
- 易用性 – 在我們例子中的代碼量和MVP的差不多乙漓,但是在實(shí)際開發(fā)中,我們必須把View中的事件指向Presenter并且手動(dòng)的來更新View释移,如果使用綁定的話叭披,MVVM代碼量將會(huì)小的多。
-
Controller
主要作為調(diào)度者玩讳,居于中心位置涩蜘。客串部分View相關(guān)功能熏纯。 -
ViewModel
專門做“顯示邏輯”皱坛,并且用屬性觀察者做綁定,必要的時(shí)候用Notification豆巨。 - 在Swift中剩辟,
ViewModel
和Model推薦用Struct;Logic傾向于用class往扔。從一個(gè)簡單直觀的概念來說贩猎,ViewModel需要保持輕量級(jí),跟隨頁面走萍膛,隨時(shí)準(zhǔn)備修改吭服。Model也是輕量級(jí),跟隨后臺(tái)API定義走蝗罗,只是個(gè)數(shù)據(jù)結(jié)構(gòu)艇棕,隨時(shí)準(zhǔn)備修改蝌戒。而Logic就顯得比較大,考慮穩(wěn)定沼琉,考慮復(fù)用北苟。 - 增加
Logic
類,負(fù)責(zé)業(yè)務(wù)邏輯打瘪,比如從網(wǎng)絡(luò)取數(shù)據(jù)友鼻,修改數(shù)據(jù)庫,檢查用戶名合法性闺骚,具體的響應(yīng)邏輯彩扔,監(jiān)聽后的具體處理等等。
3. VIPER
- 任務(wù)均攤 – 毫無疑問僻爽,VIPER是任務(wù)劃分中的佼佼者虫碉。
- 可測試性 – 不出意外地,更好的分布性就有更好的可測試性胸梆。
- 易用性 – 最后你可能已經(jīng)猜到了維護(hù)成本方面的問題蔗衡。你必須為很小功能的類寫出大量的接口。
-
View
: 也是View + Controller -
Present
:相當(dāng)于ViewModel乳绕,叫展示器 -
Interactor
:交互器绞惦,側(cè)重于業(yè)務(wù)邏輯;從網(wǎng)絡(luò)取數(shù)據(jù)洋措,數(shù)據(jù)庫等功能都在這里济蝉。 -
Entity
:就是Model,僅僅是數(shù)據(jù)定義 -
WireFrame
:就是Router菠发,是頁面跳轉(zhuǎn)
參考文章
1. iOS應(yīng)用架構(gòu)談 開篇
2. 我們常見的分層架構(gòu)王滤,有三層架構(gòu)的:展現(xiàn)層、業(yè)務(wù)層滓鸠、數(shù)據(jù)層雁乡。
后記
上面很多都是一些大牛的技術(shù)經(jīng)驗(yàn)之談,感興趣的給個(gè)贊或者關(guān)注糜俗,謝謝~~~~