[其他]編寫可讀代碼的藝術筆記
做一下筆記
註解
註解應該說明「做甚麼」「為什麼」還有「怎麼做」
如何開始寫註解
- 不管心裡想什麼,先寫下來
- 讀一下這段註解,看看有什麼地方可以改進
- 不斷改進
不需要註解
- 能從程式碼快速推斷的事實
- 用來粉飾爛的程式碼的「柺杖式註解」
該註解的地方
- 對於程式碼為什麼寫成這樣而不是那樣的內在理由
- 程式碼中的缺陷,使用TODO:
- 常數背後的故事,為什麼使用這個值
站在讀者立場
- 預料程式中那些地方會讓讀者說"阿?",並加上註解
- 為普通讀者意料之外的行為加上註解
- 在文件/類別的級別上使用"全局觀"解釋所有的部份如何一起工作
- 用註解來總結程式碼,讓讀者不致於迷失在細節
橡皮鴨技術
如果不能把問題說明拜或者用詞語來做設計,估計是少了甚麼東西或者什麼東西缺少定義,把一個問題畫者想法變成語言真的可以讓它具體。
- 找一個橡皮鴨子。你可以去借,去偷,去搶,去買,自己製作……反正你要搞到一個橡皮鴨子。
- 把這個橡皮鴨子放在你跟前。標準做法是放在你的桌子上,電腦顯示器邊,或是鍵盤邊,反正是你的跟前,面朝你。
- 然後,打開你的源代碼。不管是電腦裡的還是打印出來的。
- 對著那隻橡皮鴨子,把你寫下的所有代碼,一行一行地,精心地,向這只橡皮鴨子解釋清楚。記住,這是解釋,你需要解釋出你的想法,思路,觀點。不然,那只能算是表述,而不是解釋。
- 當你在向這只始終保持沉默的橡皮鴨子解釋的過程中,你會發現你的想法,觀點,或思路和實際的代碼相偏離了,於是你也就找到了代碼中的bug。
- 找到了BUG,一定要記得感謝一下那個橡皮鴨子哦。
少寫程式碼
最好的程式就是沒有程式,可以由下列幾項加強:
- 減少需求
- 解決更簡單的問題
- 從項目中消除不必要的部份,不要過度設計
- 重新考慮需求,解決版本中最簡單的問題,只要能完成工作就行
- 經常讀標準函式庫的API(每隔一段時間,花十五分鐘閱讀標準函式庫中的所有函數/模組/類別的名字),了解有什麼可以用
測試與程式碼的特徵及設計
測試性差的程式碼
特徵 |
可測試性的問題 |
設計問題 |
使用全域變數 |
對於每個測試都要重置所有的全域變數狀態,否則不同的測試會互相影響。 |
很難理解那些函數有副作用,沒辦法獨立考慮每個函數,要考慮整個程式才能理解是不是所有的程式碼都能作用。 |
對於外部組件有大量依賴的程式碼 |
很難寫任何測試,因為要有很多初始設定,人們會避免寫測試。 |
系統可能因為某一依賴失敗而失敗,對於改動來講很難知道會產生什麼樣的影響。 很難重構,系統會有更多的失敗模式,需要有更多的恢復模式。 |
程式碼有不確定的行為 |
測試會很古怪而且不可靠,經常失敗的測試最終會被忽略。 |
程式可能會有條件競爭或者其他難以重現的bug。 |
測試性好的程式碼
特徵 |
可測試性的問題 |
設計問題 |
類別中只有很少或者沒有內部狀態 |
容易寫出測試,因為要測試一個方法只要少量的設置,而且有較少的隱藏狀態需要檢查。 |
有較少狀態的類別更簡單,更容易理解。 |
類別/函數只做一件事 |
測試它只要用較少的測試案例。 |
較小/較簡單的組件更加模組化,系統有更少的耦合。 |
每個類別對於其他類別的依賴很少(低耦合) |
每個類別可以獨立測試,比多個類別一起測試容易。 |
系統可以並行開發,可以很容易修改或刪除類別,不會影響到系統的其他部份。 |
函數的介面(interface)簡單,定義明確 |
有明確的行為可以測試 測試簡單介面的工作量較少。 |
介面更容易讓程式員學習,並且重用的可能性更大。 |
常見問題
- 犧牲真正程式碼的可讀性
- 執著100%的測試覆蓋率
- 讓測試成為產品開發的阻礙