原文作者:Daniel Himmelein
原文連結:http://himmele.blogspot.com/2012/01/how-do-you-read-source-code.html
所以要先研究這些hubs,並且瞭解它們所擔負的責任。即使是大型軟體,通常也只有為數不多的hubs。因此,你不需要害怕數百萬行代碼,因為hubs會指引你悠遊其中。如果我們看一下Android OS,我會說以下類別是hubs:Zygote、ActivityManagerService、WindowManagerService、PackageManagerService、ConectivityService以及SurfaceFlinger。你看,才六個元件 :-)。你可以在小一點的規模重複這個遊戲,以Andorid UI framework來說,View、ViewFroup以及ViewRoot是hubs,許多UI元件都從上建構出來。這種化約的手法對於其他的軟體系統也同樣有效,像是作業系統、檔案系統、網路堆疊、網際網路後端平台等等。如果想瞭解更多hubs與網絡理論,我推薦Albert-Laszlo Barabasi的書Linked。
下一步,在識別出hubs之後,你需要試著瞭解hubs之間的互動模式。它們的互動會奠基於不同的機制,可能是純粹的API呼叫,或訊息傳遞(message queue或IPC calls)。為了瞭解hubs之間的依賴關係,我建議畫出hubs的部份圖形、它們的關係以及互動流程。舉例來說,看一下我之前的一篇關於Android架構模式的文章。在第七頁,有一張關於Andorid如何開始activities、services、content provider的圖,這些元件位於他們專屬的Linux行程中。透過了數次的ActivityManagerService、Zygote行程以及app行程之間的互動,才完成了這件事情。
如你所見,獲取大局觀的手法是透過由上而下地識別出hubs以及瞭解它們之間的互動。為了深入挖掘軟體系統特定部份,我們必須改變我們閱讀原始碼的模式。所以,我們會切換到由下而上的方式去觀察模組、類別、資料結構、方法、函式等等。然後,我們就能夠結合這兩種代碼閱讀方式。這種總結由上而下以及由下而上所獲得心得的方法就叫作downward causation。
我認為由下而上的手法最好從那些給予hubs呼吸的主動元件(threads、actors、processes)開始。這是因為要瞭解並推演一些代碼時,你必須瞭解hubs執行時的環境。所以,確認哪些主動元件運行了系統代碼的哪些部份,試著瞭解它們之間互動時是如何進行以及在何時進行。這會幫助你達成閱讀代碼的主要目的,也就是能夠思考並推演軟體系統代碼的所有面向(僅依賴你的腦袋而不用外部工具的幫忙,像除錯器 :-))。
栽進部份代碼的細節最好的方式就是試驗看看。我會透過加進一些logging代碼或在假設其行為後寫一點測試。另一個方式就是對代碼作點修改,然後看看在新的情況下行為變成如何。把系統弄掛也能幫助你學習它。 ;-)
當閱讀代碼時,總是要問自己:"它是如何運作的?"以及"為何開發者要這麼作?"這很可能讓你好幾晚都睡不好,不過也會讓你變成更好的軟體工程施以及架構師。任何讓自己對於閱讀代碼變得更好的方法都會幫助你開發出更強健的除錯與分析技術,然後你就可以實作新功能,修正臭蟲,或作一些重構。
透過思考與反思你正在閱讀的原始碼,你將會學到許多撰寫軟體系統與平台的技術。除此以外,你也可以從糟糕的軟體學到如何在開發系統時避免同樣的錯誤。此外,這邊有兩篇文章,是關於如何撰寫出好的代碼與軟體系統。Rich Hickey在InfoQ的演講"Simple made easy",以及Erlang programming rules and conventions。不論你所使用的編程語言為何,這兩篇文章都非常傑出有幫助。所以,閱讀原始碼是非常好玩的。也許下次不要讀又一本的軟體書籍,而是閱讀一些原始碼(GitHub是一個很好的集散地)。
由於需要一些能夠堅持下去的動力才能夠跳進巨大的代碼庫,我建議挑選能提供一些樂趣以及目的的專案 :-)。或許下面的列表包含了一個對你有趣的專案...
原文連結:http://himmele.blogspot.com/2012/01/how-do-you-read-source-code.html
如果這個世界就像Marc Andreessen與我所認為的一樣,正在被軟體吞噬,你要如何[讀|吞]原始碼?好吧,讓我們先回答究竟為何你需要很會閱讀原始碼。首先,搞懂事物是如何運作的總是樂趣無窮,透過閱讀程式碼,我們就是對有趣的軟體系統與專案在做這件事。另一個閱讀原始碼的理由是為了透過別人的經驗以及他們的錯誤,能夠更好地(並更快地)閱讀以及撰寫軟體。如果你參與一個新的軟體公司或開放原始碼計畫,你很有可能要與一個既存的巨大代碼庫奮戰,所以你需要能夠很快的熟悉它,然後實作測試以及功能,或修正錯誤。閱讀原始碼的主要目的永遠都是為了理解軟體系統的所有面貌。在這篇文章中,我提供一些閱讀時的建議與模式,這些都讓我的軟體工程師生涯輕鬆許多。 :-)
所以現在的主要問題是:你要如何閱讀原始碼?在你一頭栽進一個軟體專案的原始碼之前,你必須確認你擁有足夠的相關知識以瞭解軟體的特定區塊。因此,你需要從閱讀文件開始以獲取大的概念,以及閱讀與該軟體平台/產品相關的資訊科學,或部份領域(像是Windows apps、Mac OS X、iOS apps、Android apps、作業系統、電腦網路、瀏覽器、搜尋引擎、資料庫...)。你不需要知道該主題的所有東西,但是你必須能夠瞭解該軟體平台/產品的核心抽象概念與基本的建構元件。也就是說,在開始撰寫你自己的Linux排程演算法前,你應該要知道甚麼是processes、threads、semaphores等等(可參考Andrew S. Tanenbaum的Modern Operating Systems)。在開始之前,你也應該知道Linux特定的process管理機制(可參閱Rober Love的Linux Kernel Development以及Wolfgang Mauerer的Linux Kernel Architecture)。
不過在研究一個軟體之前,你大概就已經有這類基礎了。所以我們就從閱讀原始碼的建議與模式開始吧。你將會注意到,對於所有的軟體系統或至少所有的大型軟體子系統都有一些基本的建構元件以及核心的抽象觀念會在所有的地方出現。這些元件(類別、模組、參與者、資料結構等等)就是所謂的hubs。這些hubs會是代碼庫中的多重面相或子系統。因此,hubs連接子系統,並且使得整個代碼庫看起來像是一個小世界。Hubs形塑了軟體工程師建造軟體架構的環境。它們也實作了許多核心的功能。當軟體系統逐漸成長,越來越多其他的元件會依賴於這些hubs。(譯註:這邊所謂的hubs,有時會以隱喻的方式出現)
所以要先研究這些hubs,並且瞭解它們所擔負的責任。即使是大型軟體,通常也只有為數不多的hubs。因此,你不需要害怕數百萬行代碼,因為hubs會指引你悠遊其中。如果我們看一下Android OS,我會說以下類別是hubs:Zygote、ActivityManagerService、WindowManagerService、PackageManagerService、ConectivityService以及SurfaceFlinger。你看,才六個元件 :-)。你可以在小一點的規模重複這個遊戲,以Andorid UI framework來說,View、ViewFroup以及ViewRoot是hubs,許多UI元件都從上建構出來。這種化約的手法對於其他的軟體系統也同樣有效,像是作業系統、檔案系統、網路堆疊、網際網路後端平台等等。如果想瞭解更多hubs與網絡理論,我推薦Albert-Laszlo Barabasi的書Linked。
下一步,在識別出hubs之後,你需要試著瞭解hubs之間的互動模式。它們的互動會奠基於不同的機制,可能是純粹的API呼叫,或訊息傳遞(message queue或IPC calls)。為了瞭解hubs之間的依賴關係,我建議畫出hubs的部份圖形、它們的關係以及互動流程。舉例來說,看一下我之前的一篇關於Android架構模式的文章。在第七頁,有一張關於Andorid如何開始activities、services、content provider的圖,這些元件位於他們專屬的Linux行程中。透過了數次的ActivityManagerService、Zygote行程以及app行程之間的互動,才完成了這件事情。
如你所見,獲取大局觀的手法是透過由上而下地識別出hubs以及瞭解它們之間的互動。為了深入挖掘軟體系統特定部份,我們必須改變我們閱讀原始碼的模式。所以,我們會切換到由下而上的方式去觀察模組、類別、資料結構、方法、函式等等。然後,我們就能夠結合這兩種代碼閱讀方式。這種總結由上而下以及由下而上所獲得心得的方法就叫作downward causation。
我認為由下而上的手法最好從那些給予hubs呼吸的主動元件(threads、actors、processes)開始。這是因為要瞭解並推演一些代碼時,你必須瞭解hubs執行時的環境。所以,確認哪些主動元件運行了系統代碼的哪些部份,試著瞭解它們之間互動時是如何進行以及在何時進行。這會幫助你達成閱讀代碼的主要目的,也就是能夠思考並推演軟體系統代碼的所有面向(僅依賴你的腦袋而不用外部工具的幫忙,像除錯器 :-))。
栽進部份代碼的細節最好的方式就是試驗看看。我會透過加進一些logging代碼或在假設其行為後寫一點測試。另一個方式就是對代碼作點修改,然後看看在新的情況下行為變成如何。把系統弄掛也能幫助你學習它。 ;-)
當閱讀代碼時,總是要問自己:"它是如何運作的?"以及"為何開發者要這麼作?"這很可能讓你好幾晚都睡不好,不過也會讓你變成更好的軟體工程施以及架構師。任何讓自己對於閱讀代碼變得更好的方法都會幫助你開發出更強健的除錯與分析技術,然後你就可以實作新功能,修正臭蟲,或作一些重構。
透過思考與反思你正在閱讀的原始碼,你將會學到許多撰寫軟體系統與平台的技術。除此以外,你也可以從糟糕的軟體學到如何在開發系統時避免同樣的錯誤。此外,這邊有兩篇文章,是關於如何撰寫出好的代碼與軟體系統。Rich Hickey在InfoQ的演講"Simple made easy",以及Erlang programming rules and conventions。不論你所使用的編程語言為何,這兩篇文章都非常傑出有幫助。所以,閱讀原始碼是非常好玩的。也許下次不要讀又一本的軟體書籍,而是閱讀一些原始碼(GitHub是一個很好的集散地)。
由於需要一些能夠堅持下去的動力才能夠跳進巨大的代碼庫,我建議挑選能提供一些樂趣以及目的的專案 :-)。或許下面的列表包含了一個對你有趣的專案...
Software projects
- Google Android
- Minix (Monolithic OSes are not here to stay forever :-))
- Linux Kernel
- Microsoft Singularity
- Erlang
- CouchDB
- Google Chrome
- Microsoft ASP.NET MVC
- TinyVM
- Ext4 FS
- TCP/IP networking stacks: NetBSD, lwIP
- Apache Lucene
- Apache Hadoop
- Microsoft .NET Bio
- QNX Neutrino RTOS (Sadly the QNX Neutrino RTOS is not shared source anymore, but hopefully a great software company will buy QNX Software Systems some day and make this great OS really huge :-))
留言
張貼留言