iOS應(yīng)用架構(gòu)漫談

開篇有話說:

2018年伊始罚拟,從東方航空iOS客戶端7.0+ 版本開始付魔,我便著手參與了其漫長的重構(gòu)之路生百,實(shí)踐之路總是令人亦喜亦憂孙蒙,好在功夫不負(fù)有心人项棠,呈現(xiàn)給了用戶更加流暢的使用體驗(yàn)。期間也總結(jié)了一些經(jīng)驗(yàn)挎峦,現(xiàn)在想來系統(tǒng)回顧一下在這個(gè)過程當(dāng)中我和我的團(tuán)隊(duì)所遇到的一些值得記錄的問題香追。

首先,當(dāng)我們開始討論客戶端應(yīng)用架構(gòu)的時(shí)候坦胶,我們最終在討論些什么透典?我沒有寫過java,對于Android客戶端不是很了解顿苇,下面的討論會(huì)專注于iOS應(yīng)用方面峭咒,但是我想無論是什么平臺(tái),架構(gòu)思想應(yīng)該是相通的纪岁,只是實(shí)現(xiàn)手段不同罷了凑队。

圖1

一般來說,大部分應(yīng)用實(shí)際做的事情如上圖所示幔翰。簡單說就是調(diào)用API漩氨,展示頁面,然后跳轉(zhuǎn)到別的地方再調(diào)API导匣,再展示頁面才菠。

確實(shí),App就是為了做這些事情而誕生的贡定,那么支撐這些事情的基礎(chǔ)包含哪些呢赋访?這就是做應(yīng)用架構(gòu)要考慮的事情。

調(diào)用網(wǎng)絡(luò)API

展示頁面

數(shù)據(jù)的本地持久化

動(dòng)態(tài)部署方案

基于上面四點(diǎn)來細(xì)說一下架構(gòu)考慮解決的問題:

如何讓業(yè)務(wù)開發(fā)工程師方便安全的調(diào)用網(wǎng)絡(luò)API缓待?如何盡可能保證用戶在各種網(wǎng)絡(luò)環(huán)境下都能有良好的體驗(yàn)蚓耽?

頁面如何組織才能盡可能降低業(yè)務(wù)方代碼的耦合度,降低業(yè)務(wù)方開發(fā)頁面的復(fù)雜度旋炒,提高他們的開發(fā)效率步悠?

當(dāng)數(shù)據(jù)需要做本地緩存時(shí),如何優(yōu)化數(shù)據(jù)在本地的存儲(chǔ)方式來盡可能的降低性能損耗瘫镇?

緊急情況下鼎兽,如何避開iOS的審核周期答姥,在不發(fā)新版本的情況下展示新的內(nèi)容給用戶,如何緊急修復(fù)bug谚咬?

上面幾點(diǎn)是針對App來說的鹦付,那么針對開發(fā)團(tuán)隊(duì)我們還需要考慮很多,例如:

高效收集用戶信息择卦,給產(chǎn)品和運(yùn)營提供數(shù)據(jù)參考敲长;

合理組織各個(gè)業(yè)務(wù)方開發(fā)的業(yè)務(wù)模塊,以及相關(guān)的基礎(chǔ)模塊秉继;

每天都會(huì)進(jìn)行的App代碼管理打包祈噪,提供給QA的測試工具;

實(shí)際上要考慮的遠(yuǎn)不止這些尚辑,還取決于App的規(guī)模復(fù)雜程度以及公司對App的定位和迭代規(guī)劃辑鲤。

所以,當(dāng)我們討論客戶端應(yīng)用架構(gòu)的時(shí)候杠茬,我們差不多都是在討論這些問題遂填。

上面細(xì)分出來的問題應(yīng)該會(huì)在后續(xù)文章中來寫,那這篇文章就是來說說一些通識澈蝙,也方便大家一起討論,對于這系列的問題有一個(gè)初步的印象撵幽。

應(yīng)用架構(gòu)設(shè)計(jì)的方法

萬事開頭難灯荧,當(dāng)我們開始著手設(shè)計(jì)并實(shí)現(xiàn)一層架構(gòu)甚至設(shè)計(jì)整個(gè)App的架構(gòu)時(shí),很多時(shí)候都感到任務(wù)艱巨如履薄冰盐杂,甚至有種無從下手的尷尬逗载,因?yàn)槊恳粋€(gè)架構(gòu)師都會(huì)有自己的一套解決問題的思路,但是不管你采用什么樣的方法链烈,高度的代碼審美能力和全局觀厉斟,以及靈活使用各種設(shè)計(jì)模式都是貫穿其中的。

下面分幾步來說說如何一步步進(jìn)入設(shè)計(jì)之路:

(1)明確解決哪些問題强衡,找到解決這些問題的充要條件擦秽。

要很清楚業(yè)務(wù)方需要什么,肯定不是為了造輪子體驗(yàn)新的技術(shù)而修改架構(gòu)方案漩勤,比如以前用的是MVC,后來又流行MVVM感挥,那如果過去MVC是個(gè)好的架構(gòu),沒有太大的缺陷越败,就不應(yīng)該一棒子推倒打死搞成MVVM触幼,畢竟適合自己的才是最好的嘛。

搞清楚充要條件很重要究飞,這將決定你的架構(gòu)是否易用置谦,提供對外的API傳的參數(shù)越少越集約堂鲤,耦合度相對而言也就越低,那么模塊維護(hù)與升級的開銷也就越低媒峡。

(2)問題應(yīng)該分類瘟栖,分模塊

這一點(diǎn)無論是不是搞架構(gòu)的工程師,必定都會(huì)舉雙手贊同吧丝蹭,不多解釋了慢宗。

(3)理清各種問題之間的依賴關(guān)系,做好注釋奔穿,建立好模塊之間的交流規(guī)范并設(shè)計(jì)模塊镜沽;

畢竟架構(gòu)往往不只是一個(gè)工程師開發(fā)和維護(hù)的,在軟件的迭代過程中贱田,會(huì)有各種需求把不同模塊的開發(fā)者聯(lián)系到一起缅茉,如果沒有條理,模塊是使用沒有規(guī)范的依據(jù)男摧,可想而知那將會(huì)是一場代碼災(zāi)難蔬墩,沒有一個(gè)工程師想來維護(hù)半天都看不明白的爛代碼,你懂的耗拓。

(4)童鞋拇颅,你可能不僅要考慮現(xiàn)在還要考慮未來,對未來可能的走向要做必要的預(yù)測乔询,以便降低兼容新模塊的成本樟插;

一個(gè)好的架構(gòu)絕對不是一勞永逸的工程,軟件是有生命的竿刁,你做出來的架構(gòu)將決定它的一生是幸福還是坎坷黄锤。

(5)先實(shí)現(xiàn)基本模塊,解決最基本的需求食拜,再用基本模塊堆疊出整個(gè)架構(gòu)鸵熟;

這個(gè)就很好的體現(xiàn)了你設(shè)計(jì)架構(gòu)的邏輯之美,基本模塊一定要嚴(yán)要求高標(biāo)準(zhǔn)负甸,在后續(xù)的擴(kuò)展過程中發(fā)現(xiàn)問題及時(shí)調(diào)整流强,否則隨著業(yè)務(wù)邏輯的擴(kuò)張所帶來的維護(hù)成本很可能消磨掉你所有的野心。

那說了這么多呻待,到底啥樣的架構(gòu)才是好架構(gòu)呢煮盼?

我默默的列出了一串標(biāo)準(zhǔn):

代碼整齊,分類分層明確带污,沒有common僵控,沒有core;

不用文檔或者少用文檔就能讓業(yè)務(wù)方上手鱼冀;

思路和方法要統(tǒng)一报破,函數(shù)名易理解悠就,不玩捉貓貓;

少的橫向依賴充易,萬不得已不出現(xiàn)跨層訪問梗脾;

接口少,接口參數(shù)少盹靴;

易測試炸茧,易擴(kuò)展;

高性能稿静;

這個(gè)是我按照自己的經(jīng)驗(yàn)根據(jù)重要性來排的梭冠,當(dāng)然沒提到的并不代表不重要,還要看業(yè)務(wù)方的具體需求改备。

補(bǔ)充:

(1)關(guān)于架構(gòu)分層

上面提到好的架構(gòu)標(biāo)準(zhǔn)當(dāng)中有提到分層明確控漠,被我一筆帶過,我想就這點(diǎn)多說一些:

其實(shí)分層這個(gè)概念由來已久悬钳,我們常見的分層架構(gòu)有三層架構(gòu)的:展示層盐捷,業(yè)務(wù)層,數(shù)據(jù)層默勾;也有四層架構(gòu)的:展示層碉渡,業(yè)務(wù)層,網(wǎng)絡(luò)層母剥,本地?cái)?shù)據(jù)層爆价。這里所說的三層四層跟TCP/IP的五層或者七層協(xié)議有所不同,就是說你根據(jù)自己的項(xiàng)目架構(gòu)在邏輯上分為幾層那就是幾層媳搪,具體叫什么做什么沒有特定的規(guī)范。

像網(wǎng)上常見的MVC架構(gòu)骤宣,MVVM架構(gòu)秦爆,這種層次劃分主要是針對數(shù)據(jù)流動(dòng)方向而言的,在實(shí)際設(shè)計(jì)當(dāng)中憔披,針對數(shù)據(jù)流動(dòng)方向做的設(shè)計(jì)和針對模塊分類做的設(shè)計(jì)會(huì)放在一起等限,就是說一個(gè)MVC架構(gòu)可以是四層:展示層,業(yè)務(wù)層芬膝,網(wǎng)絡(luò)層望门,本地?cái)?shù)據(jù)層。

那么為什么要強(qiáng)調(diào)這個(gè)呢锰霜?因?yàn)閹啄昵俺镂螅瑯I(yè)界就很流行三層架構(gòu)的說法,然后出現(xiàn)了各種文檔解說三層架構(gòu)并且喜歡把它和MVC放在一起說癣缅,以至于很多人會(huì)認(rèn)為MVC就是三層架構(gòu)厨剪,其實(shí)不是這樣的哄酝。三層架構(gòu)里面其實(shí)沒有Controller的概念,而且三層架構(gòu)的側(cè)重點(diǎn)是模塊之間的邏輯關(guān)系祷膳,MVC有controller的概念陶衅,它描述的側(cè)重點(diǎn)在于數(shù)據(jù)的流動(dòng)方向。

那么問題又來了:為什么是三層架構(gòu)流行了起來直晨,而不是四層五層架構(gòu)呢搀军?

因?yàn)椴还苁裁礃拥墓δ苣K,角色只有三種:數(shù)據(jù)生產(chǎn)者勇皇,數(shù)據(jù)加工者罩句,數(shù)據(jù)展示者,簡單來說軟件只會(huì)有三層儒士,每一層扮演一個(gè)角色的止,替他四層五層一般都是從這三層里面的一層中分出來的,所以用三層架構(gòu)來描述比較普遍着撩。

那我們?nèi)绾蝸碜龇謱幽兀?/p>

嚴(yán)格來說分層不是在架構(gòu)一開始的時(shí)候就考慮的問題诅福,雖然一般我們會(huì)按照自頂向下的方式來設(shè)計(jì)架構(gòu),但一般情況下不會(huì)上來就約定三層架構(gòu)或者四層架構(gòu)拖叙,首先確定的是基礎(chǔ)模塊的劃分氓润,之后再細(xì)分模塊,分類之后一般大多是三層薯鳍,如果發(fā)現(xiàn)某一層特別復(fù)雜龐大咖气,那就可以考慮再進(jìn)行拆分變成四層或者五層。

舉個(gè)例子:要設(shè)計(jì)一個(gè)即時(shí)通訊的服務(wù)端架構(gòu)挖滤,怎么來分層呢崩溪?

不要一上來就往三層架構(gòu)上套,這樣是設(shè)計(jì)不出好的架構(gòu)的斩松。

我們先來列舉一下要解決的問題:

1. 要完成用戶登錄退出的邏輯伶唯;

2. 解決不同用戶間數(shù)據(jù)交流的問題;

3. 解決用戶數(shù)據(jù)存儲(chǔ)的問題乳幸;

4. 如果是多臺(tái)服務(wù)器的集群,要解決用戶連接的尋址問題钧椰;

解決1需要一個(gè)鏈接管理模塊粹断,可以通過鏈接池來實(shí)現(xiàn),解決2需要一個(gè)數(shù)據(jù)交換模塊嫡霞,解決3需要有一個(gè)數(shù)據(jù)庫瓶埋,解決4有多種方案,這里我們簡單處理需要一個(gè)尋路模塊;

于是我們就有了這幾個(gè)模塊:鏈接管理悬赏,數(shù)據(jù)交換狡汉,數(shù)據(jù)庫,尋路模塊闽颇。

當(dāng)然到這里還遠(yuǎn)遠(yuǎn)沒有結(jié)束盾戴,還需要針對不同的情況對這四個(gè)模塊進(jìn)行細(xì)分,直到足夠小足夠解決具體問題為止兵多,這里就不深究了尖啡。

其實(shí)到這里還是跟幾層架構(gòu)扯不上關(guān)系,當(dāng)所有的模塊都分出來之后剩膘,你就需要開始整理這些模塊衅斩,簡單的架構(gòu)圖可能是這樣:

圖2

然后你看一下圖,1怠褐,2畏梆,3,嗯一共三層奈懒,所以那就是三層架構(gòu)啦奠涌,其實(shí)這個(gè)過程的關(guān)鍵點(diǎn)在于:找出所有需要的模塊,并把模塊放在該放的地方磷杏。

這個(gè)例子側(cè)重點(diǎn)只在如何分層溜畅,至于其他必要的東西比如數(shù)據(jù)采集,性能優(yōu)化等等都沒有放進(jìn)去极祸,看到這里慈格,相信你因該對架構(gòu)如何分層有了一個(gè)具象的理解了,是的你沒猜錯(cuò):答案就是沒有分層遥金!所謂分層已經(jīng)是架構(gòu)圖出來之后的事情了浴捆,所以你看別的架構(gòu)師在分享時(shí)上來就說這個(gè)架構(gòu)分一下幾層…之類的話,那都是人家架構(gòu)做好之后的提煉稿械,絕不是上來就用分層來左右了架構(gòu)的搭建选泻。

其實(shí)實(shí)際的iOS開發(fā)過程中,對于客戶端的架構(gòu)蘋果已經(jīng)幫我們做了絕大多數(shù)的事情溜哮,至于如何站上巨人的肩膀去眺望遠(yuǎn)方,那就是你自己的事情了色解。

(2)關(guān)于沒有common茂嗓,沒有core

為什么我不建議大家創(chuàng)建common,core這樣的文件夾呢科阎,還是有必要解釋一下述吸。

一般情況下,很多項(xiàng)目管理文件的時(shí)候都有一些存放項(xiàng)目公共類的文件夾,比如處理image,一般這些文件就.h和.m兩個(gè)文件蝌矛,單獨(dú)做一個(gè)模塊覺得沒必要道批,于是乎大家就經(jīng)常把它們放到了common里面,當(dāng)時(shí)看來并沒有什么問題呀入撒,但是隨著版本迭代隆豹,模塊擴(kuò)充增大,業(yè)務(wù)越來越復(fù)雜茅逮,后續(xù)維護(hù)的工程師在需要擴(kuò)張這些小的模塊時(shí)璃赡,不太會(huì)去考慮橫向依賴問題,因?yàn)檫@些模塊都在common里面献雅,直接進(jìn)行互相依賴是符合直覺的碉考,也不算破壞規(guī)范,于是這里就成了common代碼混亂的罪魁挺身,當(dāng)common里面的依賴關(guān)系越來越復(fù)雜侯谁,再想把它們一出來單獨(dú)做成一個(gè)模塊,已經(jīng)是愛莫能助章钾。而且使用Cocoapods來管理的項(xiàng)目墙贱。Common往往就是一個(gè)pod,很容易引起混淆伍玖。

對于一些體量巨大的App來說嫩痰,common本身就是一個(gè)粒度很大的模塊,如果不斷的把它當(dāng)做中轉(zhuǎn)站窍箍,到后來基本沒人敢動(dòng)了串纺,為什么沒有人敢整理這的common呢?

1. 原來大家都是用的好好的椰棘,爛就爛點(diǎn)纺棺,你改了,你能拍胸脯保證不出錯(cuò)嘛邪狞;

2.這么復(fù)雜的東西短時(shí)間肯定搞不好祷蝌,任務(wù)重耗時(shí)長,你的leader會(huì)同意你把眼前的功能延遲來特么搞很可能炸掉的舊代碼嘛帆卓;

3. 就算你千辛萬苦搞完了巨朦,QA肯定要再做一遍回歸測試,任務(wù)辣么大剑令,你們說服他們配合你工作嘛糊啡;

吃力不討好,這就尷尬了吁津。所以不建議開common棚蓄、core這樣的文件夾為這些很可能出現(xiàn)的問題留下后患。再小的模塊再小的代碼我建議也把它們拎出來單獨(dú)做模塊,最多就是多寫幾行代碼梭依,但相比消除common稍算、core所帶來的隱患,還是很值的役拴。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末糊探,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子扎狱,更是在濱河造成了極大的恐慌侧到,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,744評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件淤击,死亡現(xiàn)場離奇詭異匠抗,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)污抬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評論 3 392
  • 文/潘曉璐 我一進(jìn)店門汞贸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人印机,你說我怎么就攤上這事矢腻。” “怎么了射赛?”我有些...
    開封第一講書人閱讀 163,105評論 0 353
  • 文/不壞的土叔 我叫張陵多柑,是天一觀的道長。 經(jīng)常有香客問我楣责,道長竣灌,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,242評論 1 292
  • 正文 為了忘掉前任秆麸,我火速辦了婚禮初嘹,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘沮趣。我一直安慰自己屯烦,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,269評論 6 389
  • 文/花漫 我一把揭開白布房铭。 她就那樣靜靜地躺著驻龟,像睡著了一般。 火紅的嫁衣襯著肌膚如雪缸匪。 梳的紋絲不亂的頭發(fā)上翁狐,一...
    開封第一講書人閱讀 51,215評論 1 299
  • 那天,我揣著相機(jī)與錄音豪嗽,去河邊找鬼谴蔑。 笑死,一個(gè)胖子當(dāng)著我的面吹牛龟梦,可吹牛的內(nèi)容都是我干的隐锭。 我是一名探鬼主播,決...
    沈念sama閱讀 40,096評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼计贰,長吁一口氣:“原來是場噩夢啊……” “哼钦睡!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起躁倒,我...
    開封第一講書人閱讀 38,939評論 0 274
  • 序言:老撾萬榮一對情侶失蹤荞怒,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后秧秉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體褐桌,經(jīng)...
    沈念sama閱讀 45,354評論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,573評論 2 333
  • 正文 我和宋清朗相戀三年象迎,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了荧嵌。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,745評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡砾淌,死狀恐怖啦撮,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情汪厨,我是刑警寧澤赃春,帶...
    沈念sama閱讀 35,448評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站劫乱,受9級特大地震影響织中,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜要拂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,048評論 3 327
  • 文/蒙蒙 一抠璃、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧脱惰,春花似錦、人聲如沸采盒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,683評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嫡纠。三九已至延赌,卻和暖如春叉橱,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背掐松。 一陣腳步聲響...
    開封第一講書人閱讀 32,838評論 1 269
  • 我被黑心中介騙來泰國打工大磺, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留杠愧,地道東北人逞壁。 一個(gè)月前我還...
    沈念sama閱讀 47,776評論 2 369
  • 正文 我出身青樓袭灯,卻偏偏與公主長得像稽荧,于是被迫代替她去往敵國和親工腋。 傳聞我的和親對象是個(gè)殘疾皇子擅腰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,652評論 2 354

推薦閱讀更多精彩內(nèi)容