1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        如何高效、優(yōu)雅、愉快地閱讀項目源碼?

        共 4804字,需瀏覽 10分鐘

         ·

        2021-09-01 19:09


        代碼是形式,邏輯是神韻。

        引子

        本文探索如何閱讀成熟框架的源碼。

        溫馨提示

        欲速則不達。閱讀源碼很容易理解為就是直接去閱讀代碼本身。實際上,代碼只是形式,邏輯才是神韻。

        凡是有助于去理解邏輯,理解其原理、架構(gòu)、實現(xiàn)的,都是值得閱讀的。包括而不限于官方文檔和 API 文檔、架構(gòu)設(shè)計分析文章、原理分析文章、源碼閱讀分析文章。磨刀不誤砍柴工。準備工作做充足,充分借助各種資源輔助,閱讀源碼才能事半功倍。

        預思考

        有需求才有目標,有目標才有設(shè)計,有設(shè)計才有框架。在閱讀某個源碼模塊之前,思考若干基本問題是必要的。

        • 需求是什么?用一句話說清楚;

        • 設(shè)計目標是什么?用一句話說清楚;

        • 核心優(yōu)勢和適用場景是什么?分別用一句話說清楚;

        • 基本原理是怎樣的?先自己思考怎么實現(xiàn),然后閱讀框架原理文章;

        • 整體設(shè)計是怎樣的?先自己思考怎么設(shè)計,然后閱讀架構(gòu)設(shè)計的文章;

        • 技術(shù)難點是什么?先自己思考其中的難點及解決方案,然后閱讀相關(guān)文章;

        • 數(shù)據(jù)結(jié)構(gòu)及算法流程是如何設(shè)計的?閱讀框架的源碼解析文章。

        比如 SpringBean 模塊:

        • 需求:有一套通用機制去創(chuàng)建和裝配應(yīng)用所需要的完整的 Bean 實例,使得應(yīng)用無需關(guān)注 Bean 實例的創(chuàng)建和管理,只要按需獲取;

        • 設(shè)計目標:根據(jù)指定的配置文件或注解,生成和存儲應(yīng)用所需要的裝配完整的 Bean 實例,并提供多種方式來獲取 Bean 實例;

        • 核心優(yōu)勢:支持多種裝配方式、自動裝配、依賴關(guān)系自動注入;支持不同作用域的 Bean 實例創(chuàng)建和獲取;穩(wěn)定高效;

        • 適用場景:有大量的 Bean 需要創(chuàng)建,這些 Bean 存在復雜的依賴關(guān)系;

        • 基本原理:反射機制 + 緩存;

        • 算法流程:創(chuàng)建 bean 工廠對象 -> 掃描資源路徑,獲得 bean 的 class 文件 -> 生成 bean 定義的 beanDefinition 實例 -> 根據(jù) beanDefinitioin 實例創(chuàng)建 bean 實例并緩存到 bean 工廠對象 -> 依賴自動注入 -> 執(zhí)行鉤子方法 -> 完整的 bean 實例準備就緒。

        • 技術(shù)難點:依賴自動裝配、循環(huán)引用;解決自動依賴注入和循環(huán)引用問題需要用到緩存機制。

        需求與目標

        需求與目標往往容易混為一談。但需求不等于目標。

        • 需求是寬泛的,目標是具體的;

        • 目標是需求的一種實現(xiàn)途徑,往往是設(shè)計一個具備某些關(guān)鍵特性的系統(tǒng)或產(chǎn)品。

        目標是功能與質(zhì)量的結(jié)合體;除了功能部分,確定質(zhì)量指標也是尤為關(guān)鍵的。

        對于某個框架來說,需求、適用場景和核心優(yōu)勢,都是可以直接在官網(wǎng)或項目主頁獲取到的。如何還原框架的設(shè)計目標呢?可以從核心優(yōu)勢中獲取基本說明,更多的就要從 API 文檔里來提煉了。

        方法

        很多開發(fā)童鞋可能對閱讀源碼心生畏懼。其實讀源碼既不神秘也不復雜:寫個 Demo,打斷點,運行,然后細細揣摩。閱讀源碼就是觀摩高手出招的過程。

        1. 確立目標,通常是理解某個模塊的原理、設(shè)計或者為了解決實際問題;

        2. 寫個 demo,能夠?qū)⒅髁鞒踢\行起來;

        3. 找到框架運行的入口點,通過靜態(tài)代碼分析,大致了解整個實現(xiàn)流程;

        4. 在預估會經(jīng)過的關(guān)鍵地方打斷點,單步調(diào)試;

        5. 仔細查看主流程經(jīng)過的主路徑、每一個主要對象及其成員變量的值及變化,細細揣摩其設(shè)計意圖和方法技巧;

        6. 繪制整體流程框圖和類的交互圖;

        7. 學習和理解關(guān)鍵類及關(guān)鍵方法及實現(xiàn)(代碼)。

        閱讀源碼,要把握主要與擴展:

        • 首先把主流程及涉及到的主要類弄透徹;

        • 理解其擴展機制;

        • 理解主要擴展實現(xiàn)(需要的時候徐圖之)。

        閱讀源碼,常常要將“靜態(tài)代碼分析”和“單步調(diào)試”結(jié)合起來使用。

        靜態(tài)代碼分析

        靜態(tài)代碼分析,就是沿著方法調(diào)用鏈,“順藤摸瓜”一路點擊下去。通常能夠?qū)φw流程有一個大概的了解。

        由于框架實現(xiàn)常?;诮涌诰幊蹋袝r會遇到有多個實現(xiàn)的情形。這時,可以根據(jù)直覺和經(jīng)驗,選擇一個最有可能的默認實現(xiàn)繼續(xù)跟下去,或者通過單步調(diào)試來弄清楚是哪個具體實現(xiàn)。

        單步調(diào)試

        單步調(diào)試,是看似笨拙卻很實用的源碼閱讀方法。單步調(diào)試在以下情形尤其有用:

        • 接口調(diào)用有多個實現(xiàn),難以確定是哪個是具體實現(xiàn)時;

        • 查看某個比較復雜的具體類的成員時;

        • 理解實現(xiàn)細節(jié)時。

        框架解析

        框架的設(shè)計實現(xiàn)通常包括三層:

        • 問題域及解決方案構(gòu)成的抽象層,解決問題的核心部分;

        • 封裝和交互構(gòu)成的設(shè)計層,確保靈活性、可擴展性和應(yīng)用集成;

        • 各種細節(jié)構(gòu)成的實現(xiàn)層,用于保證性能和容錯等。

        閱讀順序是:抽象層 -> 封裝與交互層 -> 細節(jié)實現(xiàn)層 或者 抽象層 -> 細節(jié)實現(xiàn)層 -> 封裝與交互層。抽象層好比匣中的寶珠,不能干買櫝還珠的事情。

        抽象層

        抽象層即是問題求解層。技術(shù)面試中問到的原理或?qū)崿F(xiàn)機制,通常都屬于這一層。

        由于封裝和交互、實現(xiàn)細節(jié)的大量代碼往往會將用于解決問題的核心代碼“淹沒”,因此,在探索抽象層時,要學會大膽過濾封裝和細節(jié),直接跳過大量的分支條件語句,暫時跳過令人疑惑的地方,始終聚焦和直擊解決問題的核心部分。用于解決基本問題的核心代碼通常是不多的。

        比如,Bean 實例創(chuàng)建的核心代碼是 ClassPathBeanDefinitionScanner.doScan(掃描資源路徑,生成 beanDefinition 對象) 和AbstractAutowireCapableBeanFactory.doCreateBean 方法(根據(jù) beanDefinition 創(chuàng)建 bean 實例)。

        設(shè)計層

        要弄明白設(shè)計層,就要先弄清楚框架的整體設(shè)計:

        • 有哪些子模塊,子模塊的設(shè)計意圖是什么;

        • 子模塊之間的關(guān)聯(lián)是怎樣的,如何串聯(lián)成一個完整的設(shè)計意圖。

        框架的設(shè)計實現(xiàn)常常會用到設(shè)計模式。

        • 常用設(shè)計模式:工廠、單例、外觀、策略、適配器、裝飾、代理、模板、組合、觀察者、迭代器;

        • 不同問題域可能會用到的設(shè)計模式,比如 DB 驅(qū)動接口實現(xiàn)會用到生成器模式和橋接模式,web 請求處理用到職責鏈模式。

        常用設(shè)計模式的使用場景:

        • 如果需要創(chuàng)建實例,則通常離不開工廠和單例模式;

        • 如果涉及較為復雜的算法流程,部分算法需要在子類實現(xiàn),則會用到模板方法模式;

        • 如果需要多種實現(xiàn),并依據(jù)特定場景來選取使用,則會用到策略模式;

        • 如果要將客戶端接口及實現(xiàn)與框架的調(diào)用隔離,則會用到動態(tài)代理模式;

        • 如果要靈活疊加多種功能,則會用到裝飾器模式;

        • 如果涉及到事件機制,則離不開觀察者模式;

        • 如果需要在庫實現(xiàn)的基礎(chǔ)上提供簡潔接口,則通常用到外觀模式;

        • 如果要將多種實現(xiàn)與多種接口定義進行連接,則會用到橋接模式;

        • 如果需要涉及大量配置(規(guī)格)并生成實例,則通常用到生成器模式;

        • 如果涉及容器元素訪問,則離不開迭代器模式;

        • 如果需要以統(tǒng)一接口訪問整體與部分的行為,且整體由部分組成,則通常用到組合模式。

        理解基本設(shè)計模式的特征和適用場景,識別設(shè)計模式的使用,可以更自如地在框架源碼之間穿梭。

        細節(jié)層

        細節(jié)是最考驗源碼閱讀的心性了。細節(jié)藏魔鬼。關(guān)鍵細節(jié)考慮不周全,可能會導致整個設(shè)計的失敗。因此,細節(jié)層也是值得仔細推敲的。技術(shù)面試中也常??疾鞂崿F(xiàn)細節(jié)。如果能夠回答上來,大概率會讓面試官眼前一亮。

        有時,一些實現(xiàn)細節(jié)可能讓人摸不到頭腦。此時,可以上網(wǎng)搜索一下,往往會“茅塞頓開”。

        克服障礙

        閱讀成熟框架源碼,遇到的一大挑戰(zhàn)就是對象之間的錯綜復雜的交互關(guān)系。令人生畏。這實際上考驗著開發(fā)者的抽象和建模能力。

        原理流程圖

        原理流程圖非常重要,就像地圖一樣,指引人更容易地在“代碼迷宮”中穿行而不迷失方向。

        在閱讀源碼之前,設(shè)法弄到并理解框架的原理流程圖,往往能起到事半功倍的效果。就如行兵打仗,先弄清楚天時與地形。不可不重視之。

        概念圖景

        優(yōu)秀的軟件設(shè)計,往往是先建立一個比較完整的概念圖景。概念圖景,就是關(guān)于某個問題域的概念及其關(guān)聯(lián)關(guān)系的整體圖。

        譬如蓋房子吧。有的人蓋房子就是:砌磚!砌磚??!砌磚?。。∫惭b窗戶怎么辦?把其中一大塊磚墻錘空了再安。

        有的人,則會“設(shè)計先行”:

        • 原材料 => 子部件 => 組合與集成。

        • 原材料:磚、石、木、鋁、銅、玻璃等;

        • 子部件:墻、窗框、窗戶、門、地板、樓梯、鎖、通道等;

        • 房子:由子部件進行組合和集成而成;

        • 機制:子部件的組合與集成的原理支撐,比如形狀的組合與契合、承壓計算等。

        如何理清其中的復雜交互關(guān)系,從而理解其中蘊含的設(shè)計思想呢?需要先理清楚框架的概念圖景。

        有兩種技巧可以結(jié)合使用:

        • 由于接口定義了具體類的行為規(guī)范,可以通過閱讀接口定義及文檔來了解其設(shè)計思路和骨架;

        • 查看具體類的實例成員(暫不涉及方法),根據(jù)經(jīng)驗揣摩其設(shè)計意圖。

        核心類成員

        要深入到具體實現(xiàn),則無法避免核心類的閱讀。核心類往往擁有十幾個甚至幾十個成員及方法,展示出了十足的源碼閱讀勸退誠意。面對這種情況怎么辦呢?有三個技巧可以結(jié)合使用:

        • 按快捷鍵 Alt+7,可以查看該類的所有成員及方法,概覽一下,大致猜測其意圖;

        • 首先只關(guān)注那些對核心問題求解有重要影響的成員,暫時忽略那些用來提升性能、可擴展性等方面的成員;

        • 單步調(diào)試,仔細看看運行時的成員對象如何,這樣會更加直觀具體一些。比如 DefaultListableBeanFactory 這個類,單步調(diào)試后得到如下圖示:

        技術(shù)難點

        技術(shù)難點也是理解源碼實現(xiàn)的一個主要障礙。技術(shù)難點主要有三類:

        • 數(shù)據(jù)結(jié)構(gòu)與算法:比如 HashMap 用到了哈希表和紅黑樹,需要先閱讀文獻(比如《算法導論》)理解其結(jié)構(gòu)與算法;

        • 原理機制:比如 IO 讀寫、內(nèi)存管理、文件系統(tǒng)、編譯原理、網(wǎng)絡(luò)協(xié)議,先學習相關(guān)的原理機制,夯實基礎(chǔ);

        • 編程模型:特別的編程手法和技巧,比如讀 hystrix 源碼,就要先熟悉函數(shù)式編程和響應(yīng)式編程。

        如何找到論述原理機制的相關(guān)文獻呢?有一些基本方法可循:

        • 經(jīng)典書籍:比如數(shù)據(jù)結(jié)構(gòu)與算法,就有《算法導論》、《算法》、《計算機程序設(shè)計藝術(shù)》(排序與查找)等;

        • 經(jīng)典論文:一些還沒來得及寫入書籍的論文解讀,比如 Raft 算法等;

        • 技術(shù)書籍:比如 Linux 操作系統(tǒng)內(nèi)核實現(xiàn),TCP 協(xié)議詳解等;

        • 官方文檔:優(yōu)秀項目主頁的文檔部分,往往有相關(guān)原理機制的介紹,比如 ES 的官方文檔;

        • JavaDoc:優(yōu)秀源碼的 Java Doc 往往會引用相關(guān)出處,比如 AQS 的源碼;

        • 優(yōu)秀博文:優(yōu)秀博文往往有一些文獻引用,可以閱讀相關(guān)文獻引用;

        • 百科與搜索:在維基百科上搜索出處和引用來源;或者使用搜索引擎。

        越到后面,就會發(fā)現(xiàn),真正需要仔細閱讀和鉆研的書籍和論文,其實并不多?;ㄙM很多時間閱讀網(wǎng)絡(luò)文章,這些偷懶和捷徑,反而是走了彎路。

        耐心與意志

        閱讀框架源碼需要很大的耐心和意志。有點像蠶寶寶吃桑葉,需要一點一點地啃。各個擊破。在這個過程中,需要克服不少障礙,才能“修得正果”。

        可以使用多種輔助手段:

        • 邊聽音樂邊閱讀代碼;

        • 拉取代碼分支,邊讀邊做標記并提交;

        • 閱讀原理、架構(gòu)及源碼分析文章。

        小結(jié)

        源碼閱讀技能,可以說是程序員的“內(nèi)功心法”之一。若是能讀通優(yōu)秀源碼,則應(yīng)對日常編程工作游刃有余,而應(yīng)對難題則有路可循。

        路漫漫其修遠兮,吾將上下而求索。

        (感謝閱讀,希望對你所有幫助)
        來源:cnblogs.com/lovesqcc/p/14403497.html

        程序汪資料鏈接

        程序汪接的7個私活都在這里,經(jīng)驗整理

        Java項目分享  最新整理全集,找項目不累啦 04版

        堪稱神級的Spring Boot手冊,從基礎(chǔ)入門到實戰(zhàn)進階

        臥槽!字節(jié)跳動《算法中文手冊》火了,完整版 PDF 開放下載!

        臥槽!阿里大佬總結(jié)的《圖解Java》火了,完整版PDF開放下載!

        字節(jié)跳動總結(jié)的設(shè)計模式 PDF 火了,完整版開放下載!

        歡迎添加程序汪個人微信 itwang007  進粉絲群或圍觀朋友圈

        瀏覽 19
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            伊人五月 | 国产免费一区二区视频观看免费 | 动漫美女吸乳 | 中文字幕aaaaV | 亚洲人精品 电 | 北条麻妃无码免费看 | 成年免费A级毛片免费看无码 | 大香蕉日韩 | 久久不见久久见在线观看 | 张丽与黑人巨大激情视频 |