1,定義編程
讓咱們來談談代碼。編程語言
代碼重要嗎?固然,代碼就是設計(Jack W.Reeves, 1992);代碼是最有價值的交付物。編輯器
咱們須要好代碼嗎?在給「好代碼」下個定義以前,這個問題沒法回答。函數
那麼,究竟什麼是好代碼?工具
聞到硝煙味了嗎?哦不,戰爭歷來不是好東西。學習
對我而言,好代碼就是 「整潔可用」 的代碼。測試
好代碼首先必須是「可用」的代碼,「可用」 是指代碼作了它應該作的事情,並且作得不錯。 若是讓你寫求絕對值的代碼,你就不能寫成求平方根的;若是讓你作一個文本編輯器,OK,你作出來了,它不是一個圖片編輯器,它確確實實就是一個文本編輯器。可是用戶輸入一個字要一分鐘,這也不能稱之爲「可用」,由於它沒達到「不錯」的標準,固然,若是這個文本編輯器是給「慢星人」用的,你有理由認爲它是 「不錯」的。那麼,究竟怎樣才叫「應該作」,怎樣才叫「不錯」呢?也許客戶(用戶)的反應(評價)是惟一的標準答案。spa
其次它須要整潔。設計
整潔是一個相對的詞,在我看來,它惟一的做用就是令維護簡單。若是你寫的代碼不需維護(沒有BUG、完成以後永遠不會作功能改動、沒有任何其它代碼基於這些代碼編寫等等,顯然,若是知足了這些條件,沒人「有必要」來閱讀你的代碼),好比用完即拋的很簡單的一次性用品,那麼只要「可用」就好了,不須要「整潔」。值得注意的是, 這裏隱含了一個假設的前提條件:不保持代碼整潔的狀況下,你可以寫出「可用」的代碼。orm
現實生活中至關一部分(也許我能夠說大部分)代碼是須要維護的,也就意味着它們若是想成爲好代碼,必需要整潔。
在繼續探討「整潔」話題以前,也許有必要先談談「複雜度」。
2,複雜度
什麼是複雜度? 在本文中,咱們所談及的複雜度是指軟件開發中的複雜度,很難給出精確的數學定義,雖然業界已經有了各類相對嚴格的測量方法,但根據本文須要,這裏只簡單的給出本身的定義:複雜度是事物複雜程度的量化描述,其大概等價於使軟件達到可用所需耗費的勞動(智力+體力)的總和。
固然,上述定義又引出了對「勞動」的量化需求,本文更多的只須要對「複雜度「作相對的評估,不須要絕對的量化,因此這裏簡單地用通用的行業描述:勞動 = 人月。
無疑,(現有事實證實)軟件開發是複雜度很高的活動,咱們有各類方法論、工具、最佳實踐等等等,其本質都是爲了下降軟件開發的複雜度,也就是:第一,使軟件達到可用的標準;第二,儘量地減小所需勞動。
那麼,軟件開發爲何這麼複雜呢?《沒有銀彈》給出了它的回答:全部軟件活動包括根本任務——打造由抽象軟件實體構成的複雜(現實)概念結構,次要任務——使用編程語言表達這些抽象實體,在時間和空間限制內將它們映射成機器語言。相應的,軟件開發的複雜度由兩部分構成:
1) 來自根本任務:根本困難——對複雜現實狀況的抽象,這是軟件開發中固有的困難。
2) 來自次要任務:次要困難——經過特定表達方式讓計算機理解。這是受限於目前生產(方法、工具)的並不是與生俱來的困難。
更具體一些,軟件的複雜度來自這些:
1) 規模:軟件實體可能比人類有史以來創造的其餘任何實體都要複雜,計算機自己就比人類建造的大多數東西複雜,它擁有大量狀態,這使得構思、描述和測試都很困難,而軟件系統狀態又比計算機狀態多幾個數量級。同時,軟件沒有兩個部分是相同的,至少在語句級別上,若是有,咱們會將它合併成一個子函數,在這個方面,軟件系統和建築、汽車大不相同,後者存在大量重複的部分。另外它不只僅致使技術上的困難,還引起了許多管理上的問題,它使全面理解變得很困難,從而妨礙了概念上的 完整性;它使全部離散出口難以尋找和控制;它引起了大量學習和理解上的負擔,使開發慢慢地演變成一場災難。
2)(容易)變化:軟件天生就是易變的,第一,由於人們的想法自己容易產生變化;第二,人們可能有這樣的錯覺:軟件很容易變化——不須要過高的代價,相對其餘產品來講;第三,軟件必須演變才能成功。軟件實體的擴展不是簡單元素的重複添加,而必須是不一樣元素實體的添加,大多數狀況下,這些元素以非線性遞增的方式交互,所以整個軟件的複雜度以更大的非線性級數增加。
3)(缺少)一致性:物理學家和數學家都堅信本源的存在,全部複雜的表象之下都必有簡單的一致的本源存在,如基本粒子,如通用原理。軟件工程師可能缺少這種信念,他必須處理不一樣用戶習慣以及隨時間推移而變化的接口,這些變化是無規律的,僅僅因爲不一樣的人——而不是上帝——設計的結果;另外他們還須要處理各類歷史遺留系統的兼容性所帶來的問題,這每每須要保持接口和歷史接口的一致性。從本質上來講,這些都是沒必要要的,但軟件工程師必須處理它們——以及它們帶來的複雜度。
4) 不可見性:幾何抽象是強大的工具,建築平面圖、機械製圖、分子模型都幫助相關工做人員更好的理解及工做,軟件的客觀存在不具備空間的形體特性,所以沒有已有的表達方式能恰如其分的描述軟件。當咱們試圖用圖形描述軟件結構時,咱們發現它不止包含一個,而是不少相互關聯、重疊在一塊兒的圖形,現有的描述方式都是強制將關聯分割,直到能夠層次化一個或多個圖形(造成某種扁平結構)。這種缺憾限制了我的的設計過程,同時也嚴重阻礙了相互之間的交流。
3,整潔
平常生活中咱們談起整潔,頭腦中大概會浮現出這樣的場景:每樣物品都有序地擺放在它應該在的地方,一目瞭然,而且一塵不染,很是乾淨,使人愉快;同時,不那麼明顯的,整潔每每暗示着沒有多餘的東西,東西越少,越容易保持整潔。
整潔的代碼有一樣的特徵:
1) 有序,各得其所,模塊的歸模塊,接口的歸接口,實現的歸實現。
處理對於人腦來講過於複雜的東西,自古以來有效的辦法就是分解,將大的分解成小的,令人腦在某一時刻只須要思考小的部分。要作到這點,除了分解,還須要保持模塊和模塊之間聯繫儘量少,只有這樣你才能專一思考眼前這一塊,而沒必要過於擔憂它和其它模塊的相互影響。一樣,只有這樣,當軟件發生變更的時候,你纔不至於陷入焦油坑。
相關術語:結構化、分層、抽象、解耦、正交、下降依賴、大量原則(SRP、OCP、LSP…)
2) 一目瞭然。
流暢,沒有障礙,它應該就是這個樣子,而不是別的樣子。任何維護工做的第一件事是什麼?讀代碼。
相關術語:可讀、文字化編程(Kunth)、自解釋。
3) 一塵不染。
重點是保持。若是一直保持乾淨,一旦出現污點,將會顯得很是刺眼,天然會被清除。相反,一扇窗戶破了,若無人關心,最終整條街道都會腐化。
相關術語:重構、溫水煮青蛙。
4) 只作必要的事,保持簡單。
從奧卡姆開始,到建築,到飛機制造。「完成」不是指不能再往裏塞東西,而是指不能再往外拿任何東西。
相關術語:KISS、敏捷。
5) 使人愉快。
成功永遠使人愉快,美永遠使人愉快。
相關術語:詩歌
4,其它
也許你已經發現了,若是保持代碼整潔,彷佛就能夠應對多種複雜度(但不是全部),這也是爲何好代碼除了可用,還須要整潔。
本文只是描述我心目中的好代碼,並不打算說明如何編寫好代碼,那須要太多的篇幅(和太多的爭議)。因此,至此爲止。