我的 知識(shí)星球 里有人問到 Coding-iOS 這個(gè)開源項(xiàng)目值得學(xué)習(xí)嗎,這個(gè)開源客戶端有著 3500 + stars商源,看起來很受歡迎车份。
我把代碼下載下來后看了一會(huì),我的結(jié)論是:這個(gè)項(xiàng)目不值得作為優(yōu)秀項(xiàng)目進(jìn)行學(xué)習(xí)牡彻。說明一下扫沼,我并不是說這個(gè)項(xiàng)目代碼寫的爛,只是作為一個(gè)模范項(xiàng)目來學(xué)習(xí)的話庄吼,這個(gè)項(xiàng)目整體水平一般缎除。
這個(gè)項(xiàng)目的問題
細(xì)節(jié)處代碼質(zhì)量差
這個(gè)項(xiàng)目里的代碼我看到時(shí)間比較早的有 2014 年,意味著這是一個(gè)已經(jīng)持續(xù)多年的項(xiàng)目总寻。代碼的細(xì)節(jié)質(zhì)量做的很馬虎器罐,小到語法格式,大一點(diǎn)的命名渐行,再大一點(diǎn)到函數(shù)的實(shí)現(xiàn)邏輯都很普通轰坊。
隨手舉個(gè)例子,上面的代碼聲明了一組 Label祟印,本身 UILabel 縮寫成 L 已經(jīng)不是一個(gè)規(guī)范的做法了肴沫。但是如果團(tuán)隊(duì)都約定成 L 表示 Label 也是接受的,但是同一行里蕴忆,還被縮寫成了 T 和 V颤芬。團(tuán)隊(duì)稍微對(duì)代碼質(zhì)量有點(diǎn)要求應(yīng)該都不會(huì)允許這樣代碼的出現(xiàn)。
落后的資源管理
都 9012 年了,項(xiàng)目里的圖片資源沒有使用 Assets 管理站蝠,還是使用古老的 @2x @3x 圖片進(jìn)行圖片管理汰具。可以說因?yàn)闅v史原因沉衣,這個(gè)項(xiàng)目剛啟動(dòng)的時(shí)候沒有用 Assets郁副,但是到現(xiàn)在這么簡單的遷移都沒做,說明開發(fā)者對(duì)新技術(shù)的運(yùn)用很不敏感豌习。
簡單的架構(gòu)
這個(gè)項(xiàng)目里的代碼組織非常的單純存谎。繼承了 MVC 的光榮傳統(tǒng),項(xiàng)目主要邏輯分成三個(gè)文件夾 Models肥隆、Views既荚、Controllers。也許項(xiàng)目剛啟動(dòng)的時(shí)候按照這個(gè)思路去管理代碼文件還能接受栋艳,但是項(xiàng)目稍微發(fā)展大一點(diǎn)恰聘,這個(gè)結(jié)構(gòu)就會(huì)非常的不利于項(xiàng)目的維護(hù)。
比如有一個(gè)業(yè)務(wù) A吸占,為了實(shí)現(xiàn)這個(gè)業(yè)務(wù)你寫入了 XModel晴叨、YView、CController矾屯。過了一段時(shí)間后發(fā)現(xiàn)業(yè)務(wù) A 效果不好兼蕊,需要對(duì)其進(jìn)行下線。這個(gè)時(shí)候維護(hù)的人需要非常清楚的找到分散在三個(gè)文件夾里的三個(gè)代碼文件將其刪除件蚕。否則項(xiàng)目里有了無用的多余代碼孙技。這么說起來感覺也還好,實(shí)際業(yè)務(wù)中可能一個(gè)業(yè)務(wù)對(duì)應(yīng)了很多個(gè) View排作、Cell牵啦。執(zhí)行下線任務(wù) A 的開發(fā)者很可能不是之前負(fù)責(zé)的開發(fā)者。下線的可能是一個(gè) 3 年前的業(yè)務(wù)妄痪,當(dāng)時(shí)負(fù)責(zé)開發(fā)的程序員已經(jīng)離職了哈雏。這個(gè)時(shí)候維護(hù)的人是很難確切的把業(yè)務(wù)相關(guān)的代碼都找到的,就算找到了也要花很多時(shí)間衫生。尤其是這個(gè)項(xiàng)目里 MVC 下一級(jí)的層級(jí)也沒怎么區(qū)分僧著,要在幾十個(gè) Cell 里找到一個(gè)文件還是挺費(fèi)勁的。
組件化
這個(gè)項(xiàng)目沒有對(duì)業(yè)務(wù)模塊進(jìn)行組件化劃分障簿。所有的業(yè)務(wù)代碼都堆在一個(gè)項(xiàng)目里盹愚。項(xiàng)目增長的越大,維護(hù)成本就越高站故。新人的理解成本就越高皆怕。也不利于多人同時(shí)開發(fā)毅舆。
建議的學(xué)習(xí)路徑
想通過學(xué)習(xí)優(yōu)質(zhì)的開源項(xiàng)目,提高自己的編程水平這個(gè)心情可以理解愈腾。不過大多數(shù)時(shí)候?qū)W習(xí)一個(gè)真實(shí)的項(xiàng)目性價(jià)比是很低的憋活。
一個(gè)真實(shí)的項(xiàng)目常常會(huì)有這樣的問題:
- 很多設(shè)計(jì)是針對(duì)具體業(yè)務(wù)展開的,如果你不了解業(yè)務(wù)場景虱黄,你就不能明白代碼為什么這么寫悦即。這樣就導(dǎo)致你需要先熟悉這個(gè)項(xiàng)目的業(yè)務(wù),才能看的懂代碼橱乱。
- 實(shí)際開發(fā)中大概率會(huì)遇到一些 featrue 來不及開發(fā)了辜梳,先用成本的實(shí)現(xiàn)發(fā)布一版再說。所以項(xiàng)目里的代碼可能有些不錯(cuò)泳叠,有些實(shí)現(xiàn)的很差作瞄。作為項(xiàng)目而言是無所謂的,功能穩(wěn)定就行危纫,用戶使用的時(shí)候不管代碼實(shí)現(xiàn)的好不好宗挥。但是對(duì)于學(xué)習(xí)的開發(fā)者而言,花時(shí)間學(xué)習(xí)的是很爛的代碼种蝶,得不償失契耿。
- 真實(shí)項(xiàng)目中的需求是持續(xù)迭代的。很多項(xiàng)目本來是按照需求 A 設(shè)計(jì)的螃征,結(jié)果做著做著客戶要求再加一個(gè)需求 B搪桂。那么原來代碼的設(shè)計(jì)沒考慮到這點(diǎn)需求,繼續(xù)在原來的代碼上實(shí)現(xiàn)就會(huì)很蛋疼会傲。如果大家維護(hù)一個(gè)老的項(xiàng)目也會(huì)遇到這樣的場景,有個(gè)地方命名直接實(shí)現(xiàn)就好了拙泽,卻用了一個(gè)蹩腳的方式淌山。其實(shí)是因?yàn)樵瓉淼男枰骖?另外一塊功能,只是后來需求變了顾瞻,不再需要兼顧了泼疑。那么最后看代碼的人就覺得為什么不按照直接的方式來實(shí)現(xiàn)。
因此即便有一個(gè)優(yōu)質(zhì)的項(xiàng)目荷荤,學(xué)習(xí)前的成本也是挺高的退渗。
我認(rèn)為一個(gè)優(yōu)質(zhì)的項(xiàng)目分為兩塊:良好的架構(gòu)和優(yōu)秀的實(shí)現(xiàn)。就像一個(gè)大的項(xiàng)目會(huì)拆分成很多模塊一樣蕴纳,想要提高自己的編程能力也要拆分成很多小模塊去達(dá)成会油。比如你的覺得你的命名不好,代碼可讀性差古毛,你就去找這方面相關(guān)的資料去針對(duì)性的學(xué)習(xí)翻翩《夹恚可以看看《編寫可讀代碼的藝術(shù)》《Clean code》。如果你覺得自己模塊抽象能力不好嫂冻,學(xué)習(xí)一下面向?qū)ο蠼赫鳌⒃O(shè)計(jì)模式之類的。如果本身這些具體模塊的好壞自己不了解桨仿,直接學(xué)習(xí)一個(gè)優(yōu)質(zhì)項(xiàng)目也是囫圇吞棗睛低。假設(shè)有一個(gè)老外只喝過咖啡,沒喝過茶服傍。然后你給他一堆好茶葉給他喝钱雷,最后讓他總結(jié)好的茶葉有什么特點(diǎn),他也講不出個(gè)所以然來伴嗡。