<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          優(yōu)雅的閱讀框架源碼

          共 4541字,需瀏覽 10分鐘

           ·

          2021-07-08 01:20

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

          引子

          通過過來人的經(jīng)驗,探討如何優(yōu)雅的閱讀成熟框架的源碼。

          溫馨提示

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

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

          預(yù)思考

          有需求才有目標,有目標才有設(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 存在復(fù)雜的依賴關(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ā)童鞋可能對閱讀源碼心生畏懼。其實讀源碼既不神秘也不復(fù)雜:寫個 Demo,打斷點,運行,然后細細揣摩。閱讀源碼就是觀摩高手出招的過程。

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

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

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

          4. 在預(yù)估會經(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)常常基于接口編程,有時會遇到有多個實現(xiàn)的情形。這時,可以根據(jù)直覺和經(jīng)驗,選擇一個最有可能的默認實現(xiàn)繼續(xù)跟下去,或者通過單步調(diào)試來弄清楚是哪個具體實現(xiàn)。

          單步調(diào)試

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

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

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

          • 理解實現(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)建實例,則通常離不開工廠和單例模式;

          • 如果涉及較為復(fù)雜的算法流程,部分算法需要在子類實現(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é)考慮不周全,可能會導(dǎo)致整個設(shè)計的失敗。因此,細節(jié)層也是值得仔細推敲的。技術(shù)面試中也常常考察實現(xiàn)細節(jié)。如果能夠回答上來,大概率會讓面試官眼前一亮。

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

          克服障礙

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

          原理流程圖

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

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

          概念圖景

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

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

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

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

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

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

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

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

          如何理清其中的復(fù)雜交互關(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 用到了哈希表和紅黑樹,需要先閱讀文獻(比如《算法導(dǎo)論》)理解其結(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)與算法,就有《算法導(dǎo)論》、《算法》、《計算機程序設(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),真正需要仔細閱讀和鉆研的書籍和論文,其實并不多。花費很多時間閱讀網(wǎng)絡(luò)文章,這些偷懶和捷徑,反而是走了彎路。

          耐心與意志

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

          可以使用多種輔助手段:

          • 邊聽音樂邊閱讀代碼;

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

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

          小結(jié)

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

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

          (感謝閱讀,希望對你所有幫助)來源:cnblogs.com/lovesqcc/p/14403497.html
          --完--
          推薦閱讀:
          怎么接私貨?這個渠道你100%有用!請收藏!

          在看?c5fe985a4d8ff493b2f1fcbbb1732e2e.webp
          瀏覽 53
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

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

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  色中色在线视频 | 成人偷拍自拍 | 午夜理伦无码理论片国产 | 天天操中文字幕 | 自拍在线韩国 |