淺談iOS架構(gòu)(結(jié)合公司項(xiàng)目)

項(xiàng)目背景:

在移動(dòng)互聯(lián)網(wǎng)行業(yè)眷茁,公司算得上是一個(gè)元老了睛蛛,趕上了第一波移動(dòng)互聯(lián)網(wǎng)創(chuàng)業(yè)的熱潮,于是公司的APP項(xiàng)目也在那個(gè)時(shí)候應(yīng)運(yùn)而生雏婶,但是任何事物都有兩面性,有時(shí)候早也并不是好事白指,僅僅對于我們iOS的工程來說就是這樣留晚。聽前輩們講,我們APP大概經(jīng)歷了四代人開發(fā)告嘲,大概劃分一下如下:

  • 第一代:在那時(shí)候错维,會(huì)寫一個(gè)網(wǎng)絡(luò)請求,會(huì)一個(gè)tableview橄唬,你就可以在這個(gè)領(lǐng)域站得住腳赋焕,所以第一版本沒有任何設(shè)計(jì)而言,只是需要實(shí)現(xiàn)功能
  • 第二代:在iOS項(xiàng)目開發(fā)中轧坎,MVC是蘋果力推的架構(gòu)模式宏邮。經(jīng)過了一定時(shí)間積累和沉淀,公司項(xiàng)目逐漸往這個(gè)方向發(fā)展,漸漸有了一些清晰的結(jié)構(gòu)
  • 第三代:隨著公司的發(fā)展蜜氨,業(yè)務(wù)的擴(kuò)大械筛,APP的功能越來越多,越來越復(fù)雜飒炎。這時(shí)候APP整個(gè)項(xiàng)目結(jié)構(gòu)開始變得臃腫混亂埋哟,但不敢輕易重構(gòu)
  • 第四代:我們現(xiàn)在這一波人,在重構(gòu)的道路上郎汪,全力填前人留下的坑

APP架構(gòu)大概演進(jìn)路線:

MRC → ARC赤赊,MVC → 分層設(shè)計(jì), MVVM煞赢,組件化

我進(jìn)公司的時(shí)候抛计,現(xiàn)在的team leader正在對整個(gè)APP進(jìn)行重構(gòu),據(jù)他說整個(gè)APP已經(jīng)沒法繼續(xù)開發(fā)下去了照筑,結(jié)構(gòu)混亂不堪吹截。由于前面工程使用的MRC,而且當(dāng)時(shí)工程師的開發(fā)水平參差不齊凝危,造成項(xiàng)目線上崩潰率很高波俄。team leader帶著一批人,首先把整個(gè)項(xiàng)目轉(zhuǎn)變成ARC蛾默,換掉一些老的框架懦铺,自己重寫。然后項(xiàng)目被劃分為邏輯底層支鸡,業(yè)務(wù)層冬念,UI層。UI層調(diào)用業(yè)務(wù)層苍匆,業(yè)務(wù)層調(diào)用邏輯層刘急,不允許三層之間相互調(diào)用,這樣一個(gè)整個(gè)軟件架構(gòu)已經(jīng)解決了大部分的耦合了浸踩,對于后面進(jìn)來的同事可以很快了解熟悉APP叔汁,對于后續(xù)持續(xù)化開發(fā)有了質(zhì)的提升

目前APP結(jié)構(gòu):

  • 邏輯層:HTTP框架,TCP框架检碗,數(shù)據(jù)庫框架等(穩(wěn)定据块,不會(huì)隨APP業(yè)務(wù)變化的內(nèi)容)

  • 業(yè)務(wù)層:適應(yīng)公司自有業(yè)務(wù),如會(huì)員折剃,資料另假,分享等的管理(適應(yīng)公司業(yè)務(wù),隨時(shí)增加或者修改)

  • UI層:這里說UI層是簡稱怕犁,說的就是APP開發(fā)的一層边篮,下面也具體談?wù)勥@一層己莺,到了這一層我們才會(huì)談到MVC,MVVM或者是其他的一些架構(gòu)戈轿。我們APP之前在這一層使用的是傳統(tǒng)MVC開發(fā)凌受,對大多數(shù)人來說,MVC非常熟悉親切思杯,這也是Apple對于iOS開發(fā)推薦的架構(gòu)模式

MVC與MVVM:

MVC

我們所熟知的MVC其實(shí)Apple給我們提供的Cocoa MVC胜蛉,Apple提倡的MVC中,view和model是相互獨(dú)立的色乾,只通過controller來進(jìn)行交互

  • Model進(jìn)行數(shù)據(jù)管理
  • View根據(jù)數(shù)據(jù)進(jìn)行視圖渲染
  • Controller對Model以及View進(jìn)行調(diào)配

但是這里存在一個(gè)問題誊册,由于controller中本身存在一個(gè)view,所以很難做到view和controller完全獨(dú)立暖璧,因此controller要管理view的生命周期和響應(yīng)一些界面操作雖然model可以分擔(dān)一些簡單數(shù)據(jù)處理案怯,但是最終還是會(huì)發(fā)現(xiàn)controller變成了所有東西的代理和數(shù)據(jù)源。一旦業(yè)務(wù)相對復(fù)雜一點(diǎn)澎办,controller代碼量會(huì)非常大殴泰,而且隨著業(yè)務(wù)的增加,代碼量會(huì)持續(xù)增加浮驳,而model和view卻相對穩(wěn)定,這對于以后的維護(hù)是災(zāi)難性的捞魁。(我們的APP中當(dāng)時(shí)存在數(shù)個(gè)代碼5000行以上的控制器至会,重構(gòu)時(shí)的痛苦自不必多說)

有一點(diǎn)值得思考,我們都應(yīng)該遇到過這樣的場景谱俭,tableview里給cell填充數(shù)據(jù)的時(shí)候調(diào)用的方法大概是這樣

- (Void)setData:(XXXModel)model

這里大家有沒有注意到奉件,cell里面是有model的,所以這里是不是已經(jīng)違背了MVC的原則了呢累颂,但是這種情況確實(shí)是一直在我們開發(fā)的過程中發(fā)生及塘,我們也沒感覺到哪里奇怪匀油。如果嚴(yán)格遵守MVC的話,你會(huì)把對cell的設(shè)置放在controller中煤痕,不向view傳遞一個(gè)model對象,如果cell的樣式過多接谨,這樣controller的體積是不可想象的摆碉。所以其實(shí)我們在開發(fā)過程中已經(jīng)不知不覺的在修改MVC這種架構(gòu)了,因?yàn)樗_實(shí)是存在弊端的脓豪。

總結(jié)一下MVC:

  • 優(yōu)點(diǎn):在項(xiàng)目初期巷帝,MVC的確可以快速的構(gòu)建一個(gè)APP,并且結(jié)構(gòu)清晰扫夜,對于程序員來說更容易理解楞泼,上手開發(fā)很快驰徊,閱讀起來容易
  • 缺點(diǎn):隨著公司的業(yè)務(wù)增加,APP更為健壯的時(shí)候堕阔,MVC就顯得不堪重負(fù)棍厂,維護(hù)成本顯著增加,對業(yè)務(wù)的增刪改簡直是災(zāi)難印蔬,一個(gè)動(dòng)作會(huì)牽一發(fā)而動(dòng)全身

如何才是一個(gè)正確姿勢的MVC呢勋桶,我理解的如下:

  • model:給controller提供數(shù)據(jù)相關(guān)的接口,可以提供輕量級的業(yè)務(wù)接口
  • controller:管理view的什么周期侥猬,監(jiān)聽界面操作例驹,調(diào)度model和view
  • view:只用來刷新界面,如展示動(dòng)畫退唠,展示界面元素等

MVVM

MVVM從前兩三年開始在iOS開發(fā)中討論度非常高鹃锈,現(xiàn)在已經(jīng)是一種非常成熟的思想了。其初衷也是為了controller減負(fù)瞧预,把數(shù)據(jù)業(yè)務(wù)處理的部分從controller中移出去

  • model:和MVC一樣屎债,基本的數(shù)據(jù)單元
  • view:也和MVC差不多,不接受邏輯垢油,只做視圖展示
  • viewmodel:處理數(shù)據(jù)盆驹,業(yè)務(wù)邏輯

這里有幾個(gè)重要的地方:

  1. 首先可以看到controller哪里去了,其實(shí)這里view和controller可以劃歸為一層滩愁,controller只是接收view的事件躯喇,也就是用戶操作界面,然后將事件傳遞給viewmodel處理硝枉。controller在這里扮演的只是一個(gè)中間人的角色
  2. viewmodel不要包含任何view相關(guān)的東西廉丽,viewmodel之間可以有相互依賴,但是要盡量避免妻味,否則重蹈controller的覆轍正压,變得難以維護(hù)

很多人提到MVVM就提到了Reactive,實(shí)際上兩者完全沒有任何聯(lián)系责球,MVVM是一種軟件架構(gòu)焦履,而Reactive是一種編程思想,我們所說的ReactiveCocoa或者RxSwift是用這種思想編寫的一個(gè)框架棕诵,目的在于讓我們更容易實(shí)現(xiàn)這種編程模式裁良。也就是說不用這兩個(gè)框架,一樣可以實(shí)現(xiàn)MVVM校套。那么到底如何實(shí)現(xiàn)一個(gè)MVVM呢价脾,其實(shí)很簡單:

只要在MVC的基礎(chǔ)上,把Controller拆出一個(gè)ViewModel專門負(fù)責(zé)數(shù)據(jù)處理的事情笛匙,就是MVVM

拆出來的ViewModel怎么和外部通訊呢侨把,這時(shí)候就回到了我們說的Reactive犀变,iOS中我們使用KVO,Notification秋柄,block获枝,delegate和target-action都可以用來做ViewModel和外部的通訊,但是這些都不如Reactive來得優(yōu)雅骇笔,幾種方法具體比較大家可以用簡單代碼實(shí)現(xiàn)一下省店,就會(huì)知道Reactive和MVVM是天生一對了,這也是為什么提到MVVM就會(huì)提到Reactive了笨触。

總結(jié)

還有其他諸如MVCS懦傍,MVP,VIPER等架構(gòu)芦劣,有的只是看過一些介紹粗俱,有的自己稍微嘗試過。得出一個(gè)自己的感受

這些架構(gòu)都是衍生自MVC虚吟,把MVC中某個(gè)部分拆開寸认,得到一個(gè)新的部分,并制定一個(gè)規(guī)范串慰,然后就形成了新的架構(gòu)模式

一個(gè)APP在設(shè)計(jì)架構(gòu)的時(shí)候不能拘泥于這些偏塞,這些只是你掌握的基礎(chǔ)知識(shí)“铞辏看過一句話烛愧,天下架構(gòu)出自MVC。仔細(xì)想想其實(shí)有一定道理掂碱,因?yàn)樗械哪J娇梢猿橄蟪?數(shù)據(jù)管理者數(shù)據(jù)加工者慎冤,數(shù)據(jù)展示者疼燥。MVC其實(shí)已經(jīng)站在了一個(gè)很高的角度看問題,所以其實(shí)重點(diǎn)是你應(yīng)該怎么拆蚁堤,這里我們APP的原則是這樣的:

  • 能從controller里拆出去的盡量拆出去醉者,只保留最核心的部分
  • 拆出去的東西能保證有復(fù)用性
  • 盡可能的站在更高角度拆分(也就是拆分的粒度盡量大一些,不要拆分成一個(gè)個(gè)很小功能披诗,不然你工程文件的數(shù)量會(huì)太大)

這些說的都是相對的東西撬即,不是絕對的。比如呈队,我們APP有一個(gè)很簡單的頁面好友列表剥槐,只展示一個(gè)頭像,昵稱宪摧,和關(guān)注關(guān)系粒竖,這里有必要去MVVM嗎颅崩,有必要?jiǎng)冸xtableview的各種delegate嗎,一個(gè)簡單的MVC可以說十多分鐘就可以寫完蕊苗,完全沒必要去用那些技巧沿后。

一個(gè)APP的架構(gòu)設(shè)計(jì)應(yīng)該參考自己公司的業(yè)務(wù),因?yàn)槟阕龀龅臇|西是要為公司業(yè)務(wù)服務(wù)的朽砰,脫離了業(yè)務(wù)去談架構(gòu)是空談尖滚。不結(jié)合實(shí)際情況,拿著一堆理論直接上是很容易出問題的瞧柔,我們應(yīng)該在掌握了這些思想的前提下漆弄,結(jié)合自身公司的業(yè)務(wù),靈活使用才是正道胺翘辍置逻!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市备绽,隨后出現(xiàn)的幾起案子券坞,更是在濱河造成了極大的恐慌,老刑警劉巖肺素,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件恨锚,死亡現(xiàn)場離奇詭異,居然都是意外死亡倍靡,警方通過查閱死者的電腦和手機(jī)猴伶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來塌西,“玉大人他挎,你說我怎么就攤上這事〖裥瑁” “怎么了办桨?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長站辉。 經(jīng)常有香客問我呢撞,道長,這世上最難降的妖魔是什么饰剥? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任殊霞,我火速辦了婚禮,結(jié)果婚禮上汰蓉,老公的妹妹穿的比我還像新娘绷蹲。我一直安慰自己,他們只是感情好顾孽,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布瘸右。 她就那樣靜靜地躺著娇跟,像睡著了一般。 火紅的嫁衣襯著肌膚如雪太颤。 梳的紋絲不亂的頭發(fā)上苞俘,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天,我揣著相機(jī)與錄音龄章,去河邊找鬼吃谣。 笑死,一個(gè)胖子當(dāng)著我的面吹牛做裙,可吹牛的內(nèi)容都是我干的岗憋。 我是一名探鬼主播,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼锚贱,長吁一口氣:“原來是場噩夢啊……” “哼仔戈!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起拧廊,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤监徘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后吧碾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體凰盔,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年倦春,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了户敬。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,991評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡睁本,死狀恐怖尿庐,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情呢堰,我是刑警寧澤屁倔,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站暮胧,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏问麸。R本人自食惡果不足惜往衷,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望严卖。 院中可真熱鬧席舍,春花似錦、人聲如沸哮笆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至福铅,卻和暖如春萝毛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背滑黔。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工笆包, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人略荡。 一個(gè)月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓庵佣,卻偏偏與公主長得像,于是被迫代替她去往敵國和親汛兜。 傳聞我的和親對象是個(gè)殘疾皇子巴粪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評論 2 355

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