什麼樣的程式碼才算是好程式碼

Web開發者發表於2012-07-13

一、定義

  讓我們來談談程式碼。

  程式碼重要嗎?當然,程式碼就是設計(Jack W.Reeves, 1992);程式碼是最有價值的交付物。

  我們需要好程式碼嗎?在給“好程式碼”下個定義之前,這個問題無法回答。

  那麼,究竟什麼是好程式碼?

  聞到硝煙味了嗎?哦不,戰爭從來不是好東西。

  對我而言,好程式碼就是 “整潔可用” 的程式碼。

  好程式碼首先必須是“可用”的程式碼,“可用” 是指程式碼做了它應該做的事情,而且做得不錯。 如果讓你寫求絕對值的程式碼,你就不能寫成求平方根的;如果讓你做一個文字編輯器,OK,你做出來了,它不是一個圖片編輯器,它確確實實就是一個文字編輯 器,但是使用者輸入一個字要一分鐘,這也不能稱之為“可用”,因為它沒達到“不錯”的標準,當然,如果這個文字編輯器是給“慢星人”用的,你有理由認為它是 “不錯”的。那麼,究竟怎樣才叫“應該做”,怎樣才叫“不錯”呢?也許客戶(使用者)的反應(評價)是唯一的標準答案。

  其次它需要整潔

  整潔是一個相對的詞,在我看來,它唯一的作用就是令維護簡單。如果你寫的程式碼不需維護(沒有BUG、完成之 後永遠不會做功能改動、沒有任何其它程式碼基於這些程式碼編寫等等,顯然,如果滿足了這些條件,沒人“有必要”來閱讀你的程式碼),比如用完即拋的很簡單的一次 性用品,那麼只要“可用”就行了,不需要“整潔”。值得注意的是, 這裡隱含了一個假設的前提條件:不保持程式碼整潔的情況下,你能夠寫出“可用”的程式碼。

  現實生活中相當一部分(也許我可以說大部分)程式碼是需要維護的,也就意味著它們如果想成為好程式碼,必須要整潔。

  在繼續探討“整潔”話題之前,也許有必要先談談“複雜度”。

二、複雜度

  什麼是複雜度? 在本文中,我們所談及的複雜度是指軟體開發中的複雜度,很難給出精確的數學定義,雖然業界已經有了各種相對嚴格的測量方法,但根據本文需要,這裡只簡單的給出自己的定義:複雜度是事物複雜程度的量化描述,其大概等價於使軟體達到可用所需耗費的勞動(智力+體力)的總和。

  當然,上述定義又引出了對“勞動”的量化需求,本文更多的只需要對“複雜度“做相對的評估,不需要絕對的量化,所以這裡簡單地用通用的行業描述:勞動 = 人月。

  無疑,(現有事實證明)軟體開發是複雜度很高的活動,我們有各種方法論、工具、最佳實踐等等等,其本質都是為了降低軟體開發的複雜度,也就是:第一,使軟體達到可用的標準;第二,儘可能地減少所需勞動。

  那麼,軟體開發為什麼這麼複雜呢?《沒有銀彈》給出了它的回答:所有軟體活動包括根本任務——打造由抽象軟體實體構成的複雜(現實)概念結構,次要任務——使用程式語言表達這些抽象實體,在時間和空間限制內將它們對映成機器語言。相應的,軟體開發的複雜度由兩部分構成:

  (1). 來自根本任務:根本困難——對複雜現實情況的抽象,這是軟體開發中固有的困難。

  (2). 來自次要任務:次要困難——通過特定表達方式讓計算機理解。這是受限於目前生產(方法、工具)的並非與生俱來的困難。

  更具體一些,軟體的複雜度來自這些:

  1. 規模:軟 件實體可能比人類有史以來創造的其他任何實體都要複雜,計算機本身就比人類建造的大多數東西複雜,它擁有大量狀態,這使得構思、描述和測試都很困難,而軟 件系統狀態又比計算機狀態多幾個數量級。同時,軟體沒有兩個部分是相同的,至少在語句級別上,如果有,我們會將它合併成一個子函式,在這個方面,軟體系統 和建築、汽車大不相同,後者存在大量重複的部分。另外它不僅僅導致技術上的困難,還引發了許多管理上的問題,它使全面理解變得很困難,從而妨礙了概念上的 完整性;它使所有離散出口難以尋找和控制;它引發了大量學習和理解上的負擔,使開發慢慢地演變成一場災難

  2.(容易)變化:軟體天生就是易變的,第一,因為人們的想法本身容易產生變化;第二,人們可能有這樣的錯覺:軟體很容易變化——不需要太高的代價,相對其他產品來說;第三,軟體必須演變才能成功。軟體實體的擴充套件不是簡單元素的重複新增,而必須是不同元素實體的新增,大多數情況下,這些元素以非線性遞增的方式互動,因此整個軟體的複雜度以更大的非線性級數增長。

  3.(缺乏)一致性:物理學家和數學家都堅信本源的存在,所有復 雜的表象之下都必有簡單的一致的本源存在,如基本粒子,如通用原理。軟體工程師可能缺乏這種信念,他必須處理不同使用者習慣以及隨時間推移而變化的介面,這 些變化是無規律的,僅僅由於不同的人——而不是上帝——設計的結果;另外他們還需要處理各種歷史遺留系統的相容性所帶來的問題,這往往需要保持介面和歷史 介面的一致性。從本質上來說,這些都是不必要的,但軟體工程師必須處理它們——以及它們帶來的複雜度。

  4. 不可見性:幾 何抽象是強大的工具,建築平面圖、機械製圖、分子模型都幫助相關工作人員更好的理解及工作,軟體的客觀存在不具有空間的形體特性,因此沒有已有的表達方式 能恰如其分的描述軟體。當我們試圖用圖形描述軟體結構時,我們發現它不止包含一個,而是很多相互關聯、重疊在一起的圖形,現有的描述方式都是強制將關聯分 割,直到可以層次化一個或多個圖形(形成某種扁平結構)。這種缺憾限制了個人的設計過程,同時也嚴重阻礙了相互之間的交流。

三、整潔

  日常生活中我們談起整潔,頭腦中大概會浮現出這樣的場景:每樣物品都有序地擺放在它應該在的地方,一目瞭然,並且一塵不染,非常乾淨,令人愉快;同時,不那麼明顯的,整潔往往暗示著沒有多餘的東西,東西越少,越容易保持整潔。

  整潔的程式碼有同樣的特徵:

  1. 有序,各得其所,模組的歸模組,介面的歸介面,實現的歸實現。

  處理對於人腦來說過於複雜的東西,自古以來有效的辦法就是分解,將大的分解成小的,使人腦在某一時刻只需要思考小的部分。要做到這點,除了分 解,還需要保持模組和模組之間聯絡儘可能少,只有這樣你才能專注思考眼前這一塊,而不必過於擔心它和其它模組的相互影響。同樣,只有這樣,當軟體發生變動 的時候,你才不至於陷入焦油坑。

  相關術語:結構化、分層、抽象、解耦、正交、降低依賴、大量原則(SRP、OCP、LSP…)

  2. 一目瞭然。

  流暢,沒有障礙,它應該就是這個樣子,而不是別的樣子。任何維護工作的第一件事是什麼?讀程式碼。

  相關術語可讀、文字化程式設計(Kunth)、自解釋。

  3. 一塵不染。

  重點是保持。如果一直保持乾淨,一旦出現汙點,將會顯得非常刺眼,自然會被清除。相反,一扇窗戶破了,若無人關心,最終整條街道都會腐化。

  4. 只做必要的事,保持簡單。

  從奧卡姆開始,到建築,到飛機制造。“完成”不是指不能再往裡塞東西,而是指不能再往外拿任何東西。

  相關術語:KISS、敏捷。

  5. 令人愉快。

  成功永遠令人愉快,美永遠令人愉快。

  相關術語:詩歌

  4. 其它:

  也許你已經發現了,如果保持程式碼整潔,似乎就可以應對多種複雜度(但不是所有),這也是為什麼好程式碼除了可用,還需要整潔

  本文只是描述我心目中的好程式碼,並不打算說明如何編寫好程式碼,那需要太多的篇幅(和太多的爭議)。所以,至此為止。

相關文章