閱讀源碼的三種境界
"沒有經(jīng)驗的技術(shù)差底子薄的初級程序員,如何閱讀項目源碼? "
"有人閱讀過 mybatis 的源碼嗎 ?就看一個初始化過程就看的已經(jīng)頭暈眼花了,小伙伴們支支招吧!"
"源碼應(yīng)該怎么閱讀,我曾經(jīng)嘗試閱讀一些源碼,例如alibaba的druid中sqlparser部分,spring-mvc,但是發(fā)現(xiàn)很吃力,都說debug是***的閱讀方式,我在debug時經(jīng)常有跟丟的現(xiàn)象……就是走著走著感覺好像進(jìn)入了一些我當(dāng)前不太關(guān)注細(xì)枝末節(jié)。 "
。。。。。。
估計很多人都有這樣的疑惑。
我非常能理解小伙伴們的痛苦,因為我也是這么痛苦著走過來的。
閱讀優(yōu)秀源碼的好處想必大家都知道,學(xué)習(xí)別人優(yōu)秀的設(shè)計,合理的抽象,簡潔的代碼...... 總之是好處多多。
但是真的把龐大的代碼放到你的面前,就如同一個巨大的迷宮,要在其中東轉(zhuǎn)西轉(zhuǎn)尋出一條路來,把迷宮的整個結(jié)構(gòu)搞清楚,理解核心思想,真心不容易。
在閱讀由面向?qū)ο蟮恼Z言如Java寫的代碼時,會發(fā)現(xiàn)接口和具體的實現(xiàn)經(jīng)常對應(yīng)不起來,不太清楚一個功能到底是怎么在哪個實現(xiàn)類中才能找到。 不像C語言,就是函數(shù)調(diào)用函數(shù),相對還好點。
如果是動態(tài)語言如Ruby,Python, 一個變量的類型甚至都不容易知道,閱讀的難度大大增加。
還有一個重要的原因,現(xiàn)在我們看到的源碼基本上都經(jīng)過若干年發(fā)展、經(jīng)過很多人不斷地完善的,枝枝蔓蔓非常多,魔鬼都在細(xì)節(jié)中。 閱讀的時候很容易陷進(jìn)去, 看了幾十層函數(shù)調(diào)用以后,就徹底懵了,就放棄了: 甭管你把源碼吹得天花亂墜, 老子再也不看了。
經(jīng)過很多痛苦的掙扎以后,我也算有一些成功的經(jīng)歷,今天用治學(xué)的三個境界來類比, 給大家分享一下:
昨夜西風(fēng)凋碧樹,獨上高樓,望盡天涯路
想把源碼搞懂,吃透,首先得登高望遠(yuǎn),瞰察路徑,明確目標(biāo)與方向,了解源碼的概貌。
所以有些準(zhǔn)備工作必須得做。
1. 閱讀源碼之前,需要有一定的技術(shù)儲備。
比如設(shè)計模式,在很多Java源碼中幾乎就是標(biāo)配,尤其是這幾個:模板方法,單例,觀察者,工廠方法,代理,策略,裝飾者。
再比如閱讀Spring源碼,肯定得先了解IoC是怎么回事,AOP的實現(xiàn)方式,CGLib,Java動態(tài)代理等,自己動手,寫點相關(guān)的代碼,把這些知識點掌握了。
2. 必須得會使用這個框架/類庫, ***是精通各種各樣的用法。
上面剛提過,魔鬼都在細(xì)節(jié)中,如果有些用法根本不知道,可能你能看明白代碼是什么意思,但是不知道它為什么這些寫。
3. 先去找書,找資料,了解這個軟件的整體設(shè)計。
都有哪些模塊? 模塊之間是怎么關(guān)聯(lián)的?怎么關(guān)聯(lián)的?
可能一下子理解不了,但是要建立一個整體的概念,就像一個地圖,防止你迷航。
在讀源碼的時候可以時不時看看自己在什么地方。
4. 搭建系統(tǒng),把源代碼跑起來!
相信我,Debug是非常非常重要的手段, 你想通過只看而不運(yùn)行就把系統(tǒng)搞清楚,那是根本不可能的!
衣帶漸寬終不悔,為伊消得人憔悴。
5. 根據(jù)你對系統(tǒng)的理解,設(shè)計幾個主要的測試案例,定義好輸入,輸出。
運(yùn)行系統(tǒng),慢慢地debug ,一步步地走,這是個死功夫,沒有辦法繞過。
Debug一遍肯定是不行的,需要Debug很多遍。
***遍盡可能拋棄細(xì)節(jié),抓住主要流程, 比如有些看起來不重要的方法就不進(jìn)去看了。
第二遍、第三遍....再去看那些細(xì)節(jié)。
一個非常重要的工作就是記筆記(又是寫作?。?,畫出系統(tǒng)的類圖(不要依靠IDE給你生成的), 記錄下主要的函數(shù)調(diào)用, 方便后續(xù)查看。
文檔工作極為重要,因為代碼太復(fù)雜,人的大腦容量也有限,記不住所有的細(xì)節(jié)。 文檔可以幫助你記住關(guān)鍵點, 到時候可以回想起來,迅速地接著往下看。
要不然,你今天看的,可能到明天就忘個差不多了。
給大家看看我做的一些筆記, 格式不重要,很隨意,方便自己看懂就行。
6. 主要的測試案例搞明白了,豐富測試案例,考慮一些分支流程。
繼續(xù)Debug......
總之,靜態(tài)地看代碼 + 動態(tài)地debug (從業(yè)務(wù)的角度), 就會慢慢揭開這個黑暗森林的面紗。
這一步會非常非常地花費時間,但是你做完了,對系統(tǒng)的理解絕對有質(zhì)的飛躍。
眾里尋他千百度,驀然回首,那人卻在燈火闌珊處。
沒有千百度的上下求索,不會有瞬間的頓悟和理解,衷心祝愿閱讀源碼的朋友們都能達(dá)到這一境界。
***一點,也是最關(guān)鍵的一點: 要能堅持下去。
我不是一個聰明人, 但是笨人自有笨辦法:什么事都架不住不斷的重復(fù),一遍看不明白,再來第二遍, 兩遍搞不明白,再來第三遍......
可能有人要問: 你怎么能這么堅持地刨根問底呢?
答案就是好奇心: 這玩意兒到底是怎么實現(xiàn)的?!
【本文為51CTO專欄作者“劉欣”的原創(chuàng)稿件,轉(zhuǎn)載請通過作者微信公眾號coderising獲取授權(quán)】