JavaScript權威Douglas Crockford:程式碼閱讀和每個人都該學的程式設計
受訪者:Douglas Crockford |
Douglas Crockford現在供職於Paypal。曾是Yahoo!的資深JavaScript架構師,他在上世紀70年代初求學期間就開始從事程式開發工作了,那時的他主修電視廣播專業,但苦於無法進入演播室工作,轉而學習了學校開設的Fortran課程。在其職業生涯中,Crockford曾先後供職於Atari、Lucasfilm和Electric Communities,以各種方式聯姻計算機與傳播媒介。深感於XML的複雜性,他發明了JSON這一廣泛用於Ajax應用的資料交換格式。Crockford曾談到如果能避免使用某些特性的話,JavaScript實際上是一門相當優雅的語言。他強調了以子集方式來管理複雜度的重要性,同時介紹了他所使用的一種程式碼閱讀方法:從清理程式碼開始。 |
作者:Peter Seibel
關於JavaScript
Seibel:在程式學習之路上有哪些令你後悔的事情?
Crockford:我瞭解一些語言,但卻一直沒有機會使用。我花了不少時間學習APL並瞭解到其衰敗的原因,但這門語言真的非常優雅,可我卻沒有花時間使用它,這太遺憾了。除此以外,我還了解其他一些語言,知道能用它們做什麼,但實際上卻並沒有機會用這些語言思考。
Seibel:我聽說你喜歡ES3版本JavaScript的簡潔性。
Crockford:嗯,最終無論怎麼對語言進行修訂,其要義都是希望促進語言的不斷成功。語言越成功,修改的代價就越大。隨著你的不斷成熟,再教育的成本就會變得更大,同時還有潛在的破壞代價,而這些成本和代價也會變得難以接受。如果你確實非常成功,那就更要小心提防所做的任何變化了。反之,如果你尚未成功,那麼就有更大的自由空間來改變了。
JavaScript成為世界上最流行的程式語言純粹是偶然。目前世界上JavaScript處理器的數量要高於任何其他語言。得益於其安全模型帶來的種種問題,JavaScript是唯一一門可在任何機器上編寫並執行的語言。 這些還嫌不夠的話,再看看那麼多嵌入了JavaScript的應用吧。Adobe的大多數應用都嵌入了JavaScript,這樣就可以在本地編寫指令碼控制這些應用了。還有其他很多應用,不勝列舉。這麼一看,JavaScript已經變得非常流行了。
JavaScript這門語言的問題在於推向市場以及標準化的過程都過於匆忙了。其大多數缺陷都沒有出現在目前的實現當中——只存在於規範中。標準說照錯的做,這聽起來太嚇人了,但這就是JavaScript的狀態。它於1999年凍結了,接下來本應走向滅亡。但Ajax的橫空出世改變了這一切,JavaScript變成了世界上最重要的程式語言。
於是,我們現在認為應該修復它。但這事應該是在2000年就開始做的,而那時並沒有這麼做,因為根本沒人關注JavaScript。現在它已經長大了。
Web環境下的JavaScript還有一點非常怪異:如果編寫伺服器端應用、桌面應用或是嵌入式應用,你不僅需要選擇語言,還要選擇特定的編譯器以及特定的執行時。但對JavaScript而言你別無選擇,你必須在所有的環境下執行。
由於要在所有環境下執行,bug就沒法修復了。如果某個瀏覽器廠商搞出個bug,他們會說“天啊,搞砸了”,下個月就會發布另一個版本,但我們卻不能指望著所有使用者都會升級。大多數人一旦在機器裡裝上IE就再也不會升級了,那些bug就會常年駐留在瀏覽器上。
Seibel:你希望JavaScript有哪些變化呢?
Crockford:我認為改進JavaScript最好的辦法就是瘦身。如果我們能夠取其精華,棄其糟粕,那JavaScript會變得更棒。我認為這個辦法也適合於HTML、HTTP和CSS。我們應該仔細思考所用的各種標準,搞清楚需要哪些特性,遺漏了哪些特性並重新審視它們,絕不應該盲目地增加新特性。
程式碼閱讀
Seibel:能否詳細談談如何進行程式碼閱讀呢?
Crockford:每次開會都讓一些人閱讀他們各自的程式碼,他們會引領我們檢視其編寫的所有內容,其他人則負責檢查。對於團隊的其他成員來說,這絕對是個學習的好機會,通過這個過程他們就可以知道自己的東西該如何與他人的相配合。
每個人都圍坐在桌邊,手裡拿一疊紙,同時還把程式碼在螢幕上打出來,大家一起閱讀。我們會在編寫程式碼的過程中加上註釋。有人會說“我看不懂這個註釋”或是“這個註釋與程式碼風馬牛不相及”。大家的意見極具價值,因為作為開發者的你是不會閱讀自己編寫的註釋的,你也根本沒有意識到自己寫的註釋誤導了讀者。有這麼多人幫助你編寫整潔的程式碼是多麼幸福的一件事啊——你會找到自己根本無法找到的缺陷。
我認為一小時的程式碼閱讀抵得上兩週的QA。這種剔除錯誤的手段真是很高效。如果你讓能力很強的同事閱讀程式碼,那麼他們周圍的新手們就會學到很多東西,而這一切是無法通過其他手段獲得的;如果新手來閱讀程式碼,那麼他會得到很多極具價值的建議。
但這件事我們不能一直留到最後再做。回憶過去,我們會在專案完成之際安排程式碼閱讀,但這個時候已經太遲了,只好取消。現在我深信程式碼閱讀應該伴隨著整個專案的生命週期。我花了很長時間才意識到這一點,這麼做的好處不勝列舉。
首先,這麼做有助於把控專案,我們能夠真切地看到大家的進度,也能及早發現是不是有人已經偏離了軌道。
我曾經管理過一些專案,馬上就到最後期限了,有人說“耶,馬上就幹完了”,然後我拿到了程式碼,發現裡面什麼都沒有,有的也是一些垃圾,離完成還遠著呢。管理層最厭惡這種事情了,我覺得程式碼閱讀能夠有效避免這種窘境的發生。
Seibel:那你需要指導別人如何進行程式碼閱讀麼?可以想象,既不想讓程式碼編寫者感覺受到侵犯,又能給出頗具價值的意見是很難的。
Crockford:沒錯,這需要給予團隊成員充分的信任,要明確界定好邊界。如果團隊不和睦,那就別指望這麼做了,這會導致團隊分崩離析。如果還沒有意識到團隊的不和睦,那這麼做很快就能發現。這個過程會讓你學到很多,也會揭示出很多問題。起初會覺得不太自然,但一旦適應後就會覺得再自然不過了。 另外,我們要編寫可讀性好的程式碼。大家都知道,整潔很重要,而程式碼風格也同樣如此。所有這一切會提升程式碼的質量並增強程式設計社群的能力。
Seibel:如何編寫可讀性好的程式碼呢?
Crockford:可讀性有幾個等級。最簡單的一級是與表達保持一致,適當地保持縮排,在適當的地方使用空格。我有一個習慣來自於早年學習Fortran的時候,那就是,我往往會使用過多的單字母變數名,這個習慣可不好。我真的在很努力改掉這個壞習慣,但太難了——這麼多年來還在與之鬥爭。
Seibel:有什麼具體的舉措可以提升程式碼的可讀性呢?
Crockford:子集的想法非常重要,尤其對於JavaScript來說更是如此,因為這門語言包含了太多的糟粕,當然其他語言也一樣。當還是個菜鳥時,我會翻閱語言規範並弄明白每個特性。我知道該如何使用這些特性並一直在用。但事實證明很多特性並非是深思熟慮的結果。
我現在想到的是Fortran,但其實所有語言都難逃這個宿命。有時語言設計者本身就錯了。依我看來,C在設計上存在很多不妥之處。
Seibel:你如何閱讀別人編寫的程式碼呢?
Crockford:清理。我會把程式碼放到文字編輯器中並開始修復。首先,我會統一標點符號,適當縮排,等等這類的事情。我有些程式可以完成這些事情,但從長遠來看自己完成會更加高效,因為這有助於我加深對程式碼的理解。Morningstar曾教會我如何完成這些事情。他非常善於重構別人的程式碼,並且這也是他所使用的方法,很好。
Seibel:你是否遇到過這種情況:看到程式碼寫得一團糟,然後進行清理,但最後發現原來的程式碼其實寫得很不錯?
Crockford:還沒遇到過。我認為隨隨便便寫出來的程式碼肯定不好。好的程式碼意味著可讀性要好。在某種程度上,如果我搞不懂程式碼的意圖,那麼寫得再好也沒用,有可能程式碼在我不關心的方面表現得很好,比如很高效、很緊湊,等等。
程式碼的可讀性是我的第一要義。它比速度還重要,可以與正確性一爭高下,可讀性是正確性的重要前提。如果可讀性不好,那就不是好程式碼,程式碼的編寫者可能做出了錯誤的權衡。
Seibel:你偏愛K&R風格?
Crockford:是的,我認為他們是對的,其最初的風格沒錯,對於JavaScript更是如此。JavaScript會自動插入分號,這樣如果將花括號放在左邊而不是右邊,那麼程式的含義就會發生天大的變化,這種變化是很糟糕的。事實表明K&R風格不會遇到這個問題,但flush風格會。
對於JavaScript來說,花括號是有著正確的擺放位置的;而其他C風格的語言則不是這樣,哪種擺放位置都可以看作是正確的。有些人喜歡flush風格的花括號,我也看過有人就風格的正確與否爭論了半天,但這些解釋都毫無意義,因為他們真正爭論的是自己在學校裡用的是什麼、在第一份工作中又用了什麼風格,或者是影響過他的某人使用了哪種風格,那這種風格就是正確的,而其他則是錯誤的。
這就好比是關於應該靠左還是靠右行駛的爭論,結果當然是無疾而終。如果住在孤島上,靠哪邊行駛都無所謂,但如果大家能達成統一確定走同一邊,整個社群都會受益無窮。
Seibel:在閱讀程式碼時你會先排版,那你會對程式碼進行多大程度上的重構呢?
Crockford:我會重新編排程式碼以便所有東西都會在使用前宣告和建立。有些語言提供了很大的靈活性,讓你無需再這麼做了。但這種靈活性我不需要。
Seibel:你曾在之前的一次演講中引用了《出埃及記》第23章第10節和第11節的內容——六年你要耕種田地,收藏土產,只是第七年你要叫地歇息,不耕不種。並建議每次第7個sprint都應該用來清理程式碼。那什麼時候做比較好呢?
Crockford:每6個週期——不管週期間是什麼都該如此。如果你是每月交付,那麼我覺得每隔半年都應該跳過一個週期,專門用來清理程式碼。
每個人的必修課:程式設計
Seibel:程式設計是不是越來越容易了,門檻逐漸降低?
Crockford:我對程式設計的興趣在於幫助其他人程式設計、設計特定的語言或程式設計工具,這樣會有越來越多的人能夠從事程式設計工作——這也是Smalltalk的初衷。Smalltalk後來的發展方向出現了變化,但最初的方向確實吸引了我。我們如何設計一門面向兒童的語言,如何為那些並非程式設計師的人們設計一種語言?
Seibel:你是不是認為每個人都應該學習程式設計,至少了解一些?
Crockford:沒錯。當今世界快被計算機控制了,為了保護自己或是讓自己更加全面,你應該瞭解這些東西的工作方式。
Seibel:有些人認為通過程式設計可以學到一種重要的思考方式,比如閱讀和數學就是不同的思考方式,但都非常重要。
Crockford:我以前也這麼想。在開始程式設計時我就有過這種想法:一切都是那麼地井然有序,我看到了之前從未接觸過的結構等東西。我在想“喔,這太神奇了。每個人都應該學習學習”,因為我突然之間感覺自己變聰明瞭。但不久之後,在與其他程式設計師交流的過程中發現,他們並沒有開竅。程式設計師其實與常人也沒什麼區別,有時他們也會出現誤解。當認識到這一點後我覺得很難過。
Seibel:那程式設計只是年輕人的專利麼?
Crockford:過去我是這麼認為的。幾年前我患有睡眠呼吸暫停的症狀,但沒有意識到。我想可能是太累了,年紀也有些大了吧,結果發現自己的注意力很難集中,甚至都沒法程式設計了,因為我的大腦沒法承載太多的東西。很多時候程式設計都需要先在腦子裡想好,然後再寫出來,但我卻不行。
我喪失了這種能力,想當然地認為是年齡太大的緣故。幸好,病情得到了好轉,於是我又開始程式設計了。現在的我程式設計水平可能比以前還要好,因為我知道如何不過多地依賴於記憶。現在的我更喜歡將程式碼文件化,因為我不敢保證下一週還能記得寫這些程式碼的意圖。事實上,有時我會檢查自己的程式碼,但會驚訝於自己怎麼會這麼寫程式碼:我壓根就不記得自己曾經這麼寫過,這些程式碼有的非常醜陋,有的卻非常優雅。我實在不知道怎麼會這樣。
Seibel:你曾說過文學程式設計就像Donald Knuth所說的那樣,是個非常棒的想法,那你使用過文學工具麼?
Crockford:沒有。我一直在考慮這個問題,併為我所使用的一些語言設計過文學工具,但我現在並沒有從事文學程式設計工作。
Seibel:這僅僅是個工具鏈問題麼?如果有現成的工具,你還會編寫文學程式麼?
Crockford:當然會了。比如說,如果使用文學風格編寫JSLint的話,那維護工作就輕鬆多了。我所說的文學風格是指在設計程式時要特別考慮到閱讀問題,這麼做會給程式帶來巨大的價值。
Seibel:你覺得文學程式設計工具的主要特徵是什麼?
Crockford:Knuth的主要貢獻在於提出了以各種順序編寫程式碼的想法。這樣,如果我所關注的東西涉及很多地方的程式碼,那麼我會將這些程式碼整合起來並加以說明,然後工具會在適當的地方解決細節問題。 他還幫助你擺脫了函式大小的困擾。理想情況下,一個函式不應該超出螢幕的範圍,這樣就能一覽無餘了。如果達不到這個要求,那可以將一個函式拆分成多個函式,如果函式對程式結構起不到什麼作用,那麼它也沒有存在的價值。
Knuth建議抓住函式的各個方面,它們很可能是緊密相關的——具有一致性,但就是太大了;有時函式確實過於龐大——他建議使用具有描述性的標籤來表示每個函式,“這個函式是:”,然後列出這些標籤。你當然可以使用函式達成目的,但這兩者並不一樣,如果使用函式,你必須要處理函式之間的通訊,等等。這麼做會引入更多與問題不相關的結構。
最後,我非常希望看到新的文學程式語言的出現。Knuth非常擅於將這些想法應用到Pascal和C當中,但我打心底想看到有人能真的設計出一種新的使用這種風格的語言。
Seibel:你讀過Knuth的文學程式麼?
Crockford:當然讀過。
Seibel:如何讀的?像小說一樣?
Crockford:沒錯,就像小說一樣。我像在讀他的散文而非程式,喜歡他的展現方式,他寫得確實好,偶爾還會搞個笑話出來。我很享受這種閱讀體驗。
Seibel:Knuth的大部頭《計算機程式設計藝術》如何?你是從頭到尾讀過這本書呢,還是將其作為參考隨時翻閱,抑或是把它束之高閣碰也不碰呢?
Crockford:除了你說的最後一種情形之外。在上大學時,有那麼幾個月我連房租都沒交,就是為了買他的書。我讀過這些書,從中得到了不少樂趣,比如在第一卷的索引有個關於拖車的笑話就很好玩。我到現在為止還沒能把書上的內容全部搞懂。Knuth對某些地方的研究要比我深入得多,但我還是喜歡這些書並把它們當作參考資料。
Seibel:你是從頭到尾逐字閱讀,跳過那些不理解的數學部分?
Crockford:是的,我會很快略讀過星號太多的部分。我試圖將熟悉Knuth的書作為招聘標準,但結果卻大失所望,根本沒幾個人讀過他的書。依我看來,任何自稱為專業程式設計師的人都應該讀過Knuth的書,至少也應該買過他的書。
Seibel:也就是說Knuth講述的是如何實現最根本的東西,然後才有全景。即便清理了平臺,但使用理性的方式構建大型系統和設計也是非常困難的。請問你是如何設計程式碼的?
Crockford:編寫程式與對程式的生命週期進行迭代是不同的。通常,編寫軟體的原因在於我們知道將要修改它,而修改任何東西都不那麼容易,因為很多時候修改意味著打破舊有的東西。
你不能期望使用這種方式完成所有事情,但還是應該盡力保證足夠的靈活性,這樣不管做什麼都能適應。這就是我的觀點。如何避免誤入死衚衕?如何保證靈活性?
這就是我喜歡JavaScript的原因之一。我發現JavaScript可以輕鬆實現重構,而重構一個繼承層次很深的類實在太痛苦了。
Seibel:你覺得自己是個科學家、工程師、藝術家、工匠還是什麼?
Crockford:我覺得自己是個作家。有時我使用英語寫作,有時使用JavaScript。歸根結底,這完全取決於交流方式以及為了促進這種交流所採取的結構。人類語言與計算機語言在很多地方都是大相徑庭的,我們需要閱讀計算機語言,因此必須與之交流,我根據語言的這種交流能力判斷計算機程式的優劣。在這個層次上,人類語言與計算機語言的差別不大。
Seibel:你對自學的程式設計師有什麼建議呢?
Crockford:兩個字:多讀。現在有不少好書,去找些好書來看吧。如果從事Web開發工作,請找一些優秀的站點,看看他們的程式碼。話雖如此,其實我不太想這麼建議。大多數Web開發者都是從“檢視原始碼”開始走上Web開發之路的,但直到現在,大多數原始碼的質量都是非常低劣的。因此有一代程式設計師都被那些低劣的示例誤導了,他們寫的程式碼質量也不高。現在的情況已經有所改觀,但依然有很多低質量的程式碼遊離於你我之間,所以我是不太想給出這個建議的。
本文節選自《程式設計人生》
相關文章
- 每個人都應該學習程式設計嗎?程式設計
- 每個程式設計師都該閱讀的10本書程式設計師
- 通過閱讀 Douglas Crockford 的原始碼學習如何寫 JSON parser(一)原始碼JSON
- 每個程式設計師都應該讀的書程式設計師
- 每個程式設計師都應該讀《Unix程式設計藝術》程式設計師
- 每個人都應該懂點函數語言程式設計函數程式設計
- 賈伯斯:每個人都應該花1年時間學習程式設計程式設計
- 國外程式設計師推薦:每個程式設計師都應該讀的非程式設計書程式設計師
- 每個程式設計師都該知道的編碼準則程式設計師
- Rework:每個程式設計師都應該讀的一本書程式設計師
- 每個程式設計師都需要學習 JavaScript 的7個理由程式設計師JavaScript
- 每個程式設計師都應該學會分解複雜的方法程式設計師
- 每個程式設計師應該閱讀的10本經典書籍程式設計師
- 每個程式設計師都該知道的10大編碼原則程式設計師
- 為什麼每個程式設計師都應該學習程式碼編譯器知識程式設計師編譯
- 每個程式設計師都應該閱讀關於資料結構和程式語言的十大演算法書籍!程式設計師資料結構演算法
- 個人閱讀 程式碼大全的閱讀與提問
- javascript權威指南閱讀筆記2JavaScript筆記
- 每個程式設計師都應該學習使用Python或Ruby程式設計師Python
- 每個Python新手都應該知道的程式設計技巧Python程式設計
- 每個程式設計師都必讀的10篇文章程式設計師
- 國外程式設計師推薦:每個程式設計師都應讀的書程式設計師
- 每個程式設計師都該知道的五大定律程式設計師
- 每個程式設計師都應該知道的基礎數論程式設計師
- 每個程式設計師都應該成為架構師程式設計師架構
- 每個人都應該知道的jQuery的提示jQuery
- 每個程式設計師都應該知道的 15 個最佳 PHP 庫程式設計師PHP
- 每個程式設計師都應該瞭解的硬體知識程式設計師
- 每個程式設計師都應該知道的下一個程式語言——Kotlin程式設計師Kotlin
- 每個程式設計師都應該參加一次 GDD程式設計師
- 每個人都該懂點的版本管理技能
- 每個程式設計師都必須遵守的程式設計原則程式設計師
- StackOverflow程式設計師推薦:每個程式設計師都應讀的30本書(轉載)程式設計師
- 每個程式設計師都應該瞭解的記憶體知識程式設計師記憶體
- 程式設計師每週該做的事情!程式設計師
- 書單推薦:每個程式設計師的程式設計之路上都應該看這11本書程式設計師
- Java 程式設計師都該懂的 HashMapJava程式設計師HashMap
- 程式設計師都應該知道的福利程式設計師