開源代碼閱讀經驗

感謝原創(chuàng)作者:leowudev 寫的很好泽疆,轉來記錄
http://www.reibang.com/p/3053054bd9da

寫在前面

作為一個程序員即供,閱讀大牛們優(yōu)秀的開源項目源碼是一個提升個人編程能力、擴展思維的重要途徑于微。在實際工作中逗嫡,相信并不是所有人接手的項目代碼都很優(yōu)雅和優(yōu)秀青自,而且很大可能因為歷史遺留、趕進度等原因驱证,導致代碼冗余延窜、模塊耦合嚴重、擴展性差和兼容性差等等抹锄, 這就有可能導致在工作中無法使個人能力得到很好的提高逆瑞,并且會導致個人的思維和眼界有所局限。

其實一種想法的實現(xiàn)往往是多種的伙单,而欠缺能力的人往往采用簡單粗暴的方式获高,另一方面,而有能力的人總能使用優(yōu)雅的方式吻育,盡可能考慮各種可能的需求變動念秧、適應各種使用途徑和場景、想到未來擴展的方式來實現(xiàn)布疼。

優(yōu)秀的開源項目正是這種有能力的人用優(yōu)雅方式實現(xiàn)想法的結晶摊趾!所以,閱讀優(yōu)秀的開源項目對個人編程的思考方式游两、知識擴展都是非常非常有幫助的砾层。

作為經常閱讀別人的優(yōu)秀開源項目的人,想給大家分享下我的閱讀經驗贱案,希望能對大家有所幫助~

正文

下面將通過我最近閱讀的奇虎360的開源項目 Replugin 作為例子肛炮,說說我閱讀源碼的方法。

1.尋找驅動力

當你開始閱讀開源項目首先你得有目的性宝踪,工作需要侨糟?個人學習?這都是很好的驅動力肴沫。

沒驅動力是很難堅持的粟害,特別是開源項目涉及到很多你不怎么了解的知識點蕴忆,很容易會覺得枯燥颤芬、晦澀。畢竟閱讀別人的代碼并不是一件快樂的事情套鹅,我們很難去完成理解代碼作者當時的思路和想法站蝠,這個過程是很痛苦的。但如果你有目標卓鹿、有意圖地去閱讀菱魔,就能在一定程度上減少這痛苦。每天給自己打下雞血吟孙,未來的你等下會為這份堅持感到驕傲澜倦!

2.瀏覽官方文檔聚蝶,對開源項目的功能、架構有大概的印象

好了藻治,有了驅動力碘勉,先別急,看看官方文檔桩卵,看看這個項目能完成什么事情和不能完成什么事情验靡,還有官方對這個項目的定位。例如 Replugin 寫得滿滿的十幾頁的 wiki 雏节,官方定位:

RePlugin是一套完整的胜嗓、穩(wěn)定的、適合全面使用的钩乍,占坑類插件化方案辞州。
完整的:讓插件運行起來“像單品那樣”,支持大部分特性
穩(wěn)定的:如此靈活完整的情況下件蚕,其框架崩潰率僅為業(yè)內很低的“萬分之一”
適合全面使用的:其目的是讓應用內的“所有功能皆為插件”
占坑類:以穩(wěn)定為前提的Manifest占坑思路
插件化方案:基于Android原生API和語言來開發(fā)孙技,充分利用原生特性

可以看到,wiki很詳細地介紹了Replugin定位和優(yōu)點排作,這時相信對技術有追求的人都會冒出一個疑問:“他們如何做到的G@病?” 這又大大激起了你的好奇心妄痪,讓你更有動力堅持下去哈雏。

很多人急功近利,馬上就開始源碼閱讀之旅了衫生,包括我裳瘪。但經過多個項目源碼的閱讀的我,會告訴你罪针,別急彭羹!我們還需要知道它怎么用。

3.在工作中或實踐中使用開源項目

本節(jié)講的不是怎么使用泪酱,這官網文檔肯定會有說明的派殷,而是講為什么使用。一個東西你連使用都不會墓阀,就想去了解他的原理毡惜?就像你開車都不會,就去了解剎車怎么把車停下來斯撮。而事實是你開車都不會经伙,你可能都分不清剎車、離合和油門是哪個跟哪個勿锅,這就去了解原理帕膜,往往會迷失方向枣氧。

所以,閱讀前先使用吧垮刹。但我不建議在實際工作項目中立刻使用作瞄,因為你原理都不清楚,有問題不好排查危纫,會影響線上用戶宗挥,這就很糟糕了。我建議的是看官方demo种蝶,然后在自己的個人練手項目中使用契耿。當對項目的使用有一定地理解了,ok螃征,可以走下一步了搪桂。

4.網上搜索針對該開源項目進行分析的優(yōu)秀文章

一個優(yōu)秀的開源項目總是有很多人閱讀并分析,然后整理寫出總結文章盯滚。既然前人都幫我們分析好了踢械,我們?yōu)槭裁床徽驹谇叭说募绨蛏侠^續(xù)往上爬,這樣就省了從腳到肩膀的力氣了魄藕。但要注意我的字眼内列,是“優(yōu)秀”的文章!現(xiàn)在很多人都寫博客背率,很多都是潦潦而談话瞧,只能說是筆記,而非總結寝姿。

像 Replugin 這樣一個“巨型”的開源項目交排,老實說,對我這種菜雞來說饵筑,很多知識點都只是略知一二埃篓,例如多進程通信、gradle編譯腳本等根资,在實際工作中很少接觸的難免會覺得難懂架专。另外,官方文檔往往不會對實現(xiàn)細節(jié)講得很細嫂冻,這時胶征,看前人的分析就很有必要了塞椎。這樣可以讓你對項目的實現(xiàn)有一定地了解桨仿,當你自己看時,你能很快懂得作者這樣做的意圖案狠。

當然服傍,如果你不想看別人的分析總結也未必不可钱雷,可能在自己閱讀過程中多點磕磕碰碰,但你總不能跳過下一步吹零!

5.對開源項目提出自己的疑問

前面做了這么多準備罩抗,你總會產生疑問吧。什么灿椅?沒有套蒂!好吧,這開源項目對你來說太簡單茫蛹,已經不值得你一讀了操刀。帶著疑問去閱讀是我認為最高效的閱讀方式,當你有了目的婴洼,而不至于在閱讀過程中迷失了方向骨坑,并且在閱讀過程中針對性的看。對一個開源項目的疑問一般可以從以下方向提出:

  • 這塊功能為什么這么做柬采?有什么好處欢唾?
  • 有沒有另外一種實現(xiàn)方式?
  • 我缺少哪些知識會阻礙我看源碼(需要去補)粉捻?

例如我在閱讀 Replugin 之前提出了幾個疑問:

  • 如何做到一處hook礁遣?借助gradle?
  • 查找坑位策略肩刃?如何替換真正的啟動組件亡脸?
  • 為什么需要聲明這么多坑位?
  • 為什么不用注入Service树酪?

好了浅碾,當你有了好奇心、驅動力续语、目的垂谢,你已經準備好了。但開始閱讀前還有一件事情先搞定:編譯源碼疮茄。

6.把開源項目下載到本地滥朱,并導入IDE,方便調試力试、測試

工欲善其事徙邻,必先利其器。沒有一個好的調試環(huán)境怎么能順心地看源碼畸裳。但幸虧GitHub讓我們能簡單地把源碼download或clone下來缰犁,很多情況都是直接用IDE打開項目就搞定了。但也有像 Replugin 一樣的,分為多個項目帅容,每個項目都是單獨編譯的颇象,這樣我們就無法只打開一個窗口來調試,很不爽并徘。這時就需要點導入技巧來搞定了遣钳。這里不打算講了,需要點篇幅麦乞,留到后面我寫Replugin閱讀總結時講蕴茴。

當然,我們還可以借助一些小技巧來幫忙我們快速閱讀源碼姐直。例如我會建一個能打印方法調用堆棧的Log工具類荐开,在一些核心的部分打印log,看下它的調用堆棧:

package com.leo;
import android.util.Log;

public class Logger {

    private final static boolean showTrace = true;
    private final static boolean onlyShowTopStack = false;

    // 過濾的方法堆棧
    private final static String[] FILTER_TRACE_PREFIX = {
            "java.lang",
            "android",
            "com.android",
            "com.leo.Logger" // 過濾掉自己
    };

    public static void i(Object obj) {
        StringBuilder msg = new StringBuilder();
        if (showTrace) {
            StackTraceElement[] stes = Thread.currentThread().getStackTrace();
            for (int i = stes.length - 1, indent = 0; i > 0; i--) {
                boolean needFilter = false;
                String clsName = stes[i].getClassName();
                for (String filter : FILTER_TRACE_PREFIX) {
                    if (clsName.startsWith(filter)) {
                        needFilter = true;
                        break;
                    }
                }
                if (needFilter) continue;

                if (i != stes.length - 1)
                    msg.append(indent(indent)).append("-> ");
                msg.append(stes[i].getClassName() + "#" + stes[i].getMethodName() + "\n");
                indent++;
            }
        }
        msg.append(" >>> " + obj + "\n");
        String showMsg = msg.toString();
        if (onlyShowTopStack) {
            String[] trace = showMsg.split("->");
            showMsg = trace[trace.length - 1];
            showMsg = showMsg.replace("->", "")
                    .replace("\n", "")
                    .trim();
        }
        Log.i("TEST", showMsg);
    }

    private static String indent(int i) {
        if (i < 0) {
            i = 0;
        }
        StringBuilder ret = new StringBuilder();
        for (int n = 0; n < i; n++) {
            ret.append(" ");
        }
        return ret.toString();
    }
}

到這里简肴,你已經全部準備就緒晃听,戰(zhàn)爭一觸即發(fā)!開始 READ THE FUCKING SOURCE CODE 吧!

7.帶著疑問閱讀源碼

戰(zhàn)爭打響砰识,在充滿迷霧的大海中能扒,我方對敵人的方位還不甚了解,但不怕辫狼,我們的指北針 —— 疑問 —— 會帶領我們直達敵方腹地初斑,我們終會揭開它的露出廬山真面目。

開源項目往往是龐大而復雜的膨处,我們在閱讀過程中真的非常容易會糾結于細節(jié)见秤,而導致閱讀混亂,迷失了方向真椿,這對閱讀的動力打擊很沉重的鹃答,往往會使人放棄。

而有了疑問就不同了突硝,你知道自己為何要看测摔,你會思考,會有自己的目的解恰,不拘泥于細節(jié)實現(xiàn)锋八,能準確地找到源碼的核心實現(xiàn)。

對于糾結細節(jié)是很多人在閱讀源碼犯的錯誤护盈,有些細節(jié)我們根本不需要去搞清楚它怎么做的挟纱,知道它做什么就可以了。一些具體的實現(xiàn)可以放到當你使用過程中遇到問題腐宋,或者對該具體實現(xiàn)產生另一個疑問時才去深究紊服,也就是說檀轨,還是帶著疑問閱讀代碼。因為一個開源項目往往是多個優(yōu)秀的人花了很多時間寫出來的結晶围苫,你想在短時間內把它完成消化,是不科學的撤师。我們專注于最感興趣的剂府、最有參考價值和最核心的部分就可以了。

8.閱讀源碼過程中多添加注釋剃盾、多做筆記

我得承認腺占,我的記憶力不好,而我也不信我的記憶痒谴。好記性不如爛筆頭衰伯,記憶終將遺忘,但所做的筆記除非被銷毀积蔚,否則永遠都會在那里意鲸,等著你去翻閱回顧。

我們把整個項目都下載下來了尽爆,首先當然是在閱讀源碼過程中添加下自己的注釋了怎顾,寫下自己的理解、疑惑漱贱,或者標記下值得借鑒參考的實現(xiàn)等等槐雾。另外,我們還需要做些簡單的總結筆記幅狮∧记浚可以紙質或者網上很多的筆記類應用。對于我這種無法直視自己的手寫字的崇摄,更傾向于用筆記類應用擎值,這也是我推薦大家用的,多端同步逐抑,不能再省心幅恋。

9.做閱讀總結,吸收和再創(chuàng)造

當你對開源項目閱讀到一定程度了泵肄,對該項目有了深刻的理解捆交,并有了自己的見解,你是不是有話要說腐巢?別憋著了品追,講出來吧!跟大家分享冯丙!寫篇博客總結下閱讀經驗肉瓦、心得和成長等等遭京,既能加深自己的印象,又能幫助到他人泞莉,何樂而不為呢哪雕?!

閱讀開源項目我們最終的目的是把其涉及到的知識點和設計實現(xiàn)思路吸收鲫趁,并且轉化為自己的功力斯嚎。這個轉化不是說你閱讀完了就轉化成功了,往往閱讀是不夠的挨厚,你還需要實踐堡僻。

例如喜歡打球的我深知看NBA球星在球場上各種變向戲耍對手,對我的過人能力幾乎沒任何幫助疫剃,只是讓我知道:“原來還能這么做呀钉疫!” 我還得自己去球場一招一式的練習,反復練習巢价,或者我根據我的身體條件牲阁,做些簡單的變種,直到這招轉化為我的肌肉記憶壤躲,我才能在比賽中自然而然地使用出來咨油。

所以我提倡再創(chuàng)造。所謂再創(chuàng)造不是讓你重復造輪子柒爵,而是能根據自己的工作需求役电,把開源項目應用到工作中。這里的應用不一定是直接引用開源項目來使用棉胀,我是不建議這么做的法瑟,因為開源項目往往考慮全面,考慮到非常多的情況的唁奢,而你項目根本不存在這樣的情況霎挟,這就是浪費。所以我建議的是:根據自己工作的需求麻掸,把開源項目的核心實現(xiàn)抽取出來酥夭,轉化為能滿足自己需求的庫來使用

而這個抽取的過程就是吸收的過程脊奋。在這個過程你遇到的問題并解決熬北,會使你對開源項目有更深刻的理解。這個過程如果你對開源項目的某個實現(xiàn)不太認同诚隙,可以嘗試改為自己的實現(xiàn)讶隐,這就是吸收。

在寫最后

非常感謝看到這里的童鞋久又,畢竟這些經驗談沒什么干貨巫延,能耐心讀到這里真的非常感謝效五!我們來總結一波閱讀源碼的步驟:

  1. 尋找驅動力
  2. 瀏覽官方文檔,對開源項目的功能炉峰、架構有大概的印象
  3. 在工作中或實踐中使用開源項目
  4. 網上搜索針對該開源項目進行分析的優(yōu)秀文章
  5. 對開源項目提出自己的疑問
  6. 把開源項目下載到本地畏妖,并導入IDE,方便調試疼阔、測試
  7. 帶著疑問閱讀源碼
  8. 閱讀源碼過程中多添加注釋戒劫、多做筆記
  9. 做閱讀總結,吸收和再創(chuàng)造

以上步驟有些可以根據實際情況跳過竿开,程序員都是聰明人谱仪,總也會隨機應變~

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末玻熙,一起剝皮案震驚了整個濱河市否彩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌嗦随,老刑警劉巖列荔,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異枚尼,居然都是意外死亡贴浙,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進店門署恍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來崎溃,“玉大人,你說我怎么就攤上這事盯质≡” “怎么了?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵呼巷,是天一觀的道長囱修。 經常有香客問我,道長王悍,這世上最難降的妖魔是什么破镰? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮压储,結果婚禮上鲜漩,老公的妹妹穿的比我還像新娘。我一直安慰自己集惋,他們只是感情好宇整,可當我...
    茶點故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布捎迫。 她就那樣靜靜地躺著宣脉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪铃肯。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天臂拓,我揣著相機與錄音厚脉,去河邊找鬼。 笑死胶惰,一個胖子當著我的面吹牛傻工,可吹牛的內容都是我干的。 我是一名探鬼主播孵滞,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼中捆,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了坊饶?” 一聲冷哼從身側響起泄伪,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎匿级,沒想到半個月后蟋滴,有當地人在樹林里發(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡痘绎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年津函,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片孤页。...
    茶點故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡尔苦,死狀恐怖,靈堂內的尸體忽然破棺而出行施,到底是詐尸還是另有隱情允坚,我是刑警寧澤,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布悲龟,位于F島的核電站屋讶,受9級特大地震影響,放射性物質發(fā)生泄漏须教。R本人自食惡果不足惜皿渗,卻給世界環(huán)境...
    茶點故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望轻腺。 院中可真熱鬧乐疆,春花似錦、人聲如沸贬养。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽误算。三九已至仰美,卻和暖如春迷殿,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背咖杂。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工庆寺, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人诉字。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓懦尝,卻偏偏與公主長得像,于是被迫代替她去往敵國和親壤圃。 傳聞我的和親對象是個殘疾皇子陵霉,可洞房花燭夜當晚...
    茶點故事閱讀 45,851評論 2 361