Clean Code: A Handbook of Agile Software Craftsmanship
關於這本書的一些心得跟重點。
書如同標題,重點在 Clean code,目標是高可讀性、有邏輯化、便於擴展的 code,避免寫出難以維護的程式碼。
命名
- Use pronounceable names
避免使用無法念的字,例如書中的例子是 genYYMMDD
,這就是一個不好的命名。
- Avoid mental mapping
我覺得這很重要,當你看到一個變數名稱的時候,要馬上可以知道此變數的作用,而不是還要 map 到其他地方。
例如用 t
代表 table
,r
代表 role
, g
代表 game
,這樣都需要把 t, r, g 的對應關係記得,並不是一種好的習慣。
- One word per concept
原本就用 status
這個名稱表示狀態,就沒有必要把 info
混在一起用,而是繼續用原本字 status
。
函數
- Be small
這是最簡單也是最難的,我們都知道一個 function 寫的又臭又長對可讀性沒有任何幫助,但是往往又會反駁說:「這段 function 很難拆開,所以寫在一起」、「拆開對可讀性也沒有幫助」。會發生這種事通常代表這個 function 已經寫壞了。
書中建議的長度是,一個 function 約 20 到 30 行左右,太長了就該拆開。
- Do one thing
function 之所以會寫長,往往就是違反此原則,記住讓函數專注做一件事情就好。
- Function arguments
函數的參數不要多,越少越好,兩個或兩個以下是最好的,三個參數的 function 就應該避免,可以考慮用物件把它包起來。
真希望 C++ 也能有原生支援 Python 的 keyword argument
- Don’t repeat yourself (The DRY principle)
不要重複寫一樣的東西,有重複的段落出現的話,可以把它寫成函式。
Others
遵循 DRY 原則,既然已經寫過,就不再寫一次了,請參考上面的連結。
- Unit test
單元測試很重要,寫專案的時候請務必要寫 unit test,並且對待他們如對待你的其他程式碼一般,Be clean,千萬不要胡亂寫過。
Error handling
- Use exceptions rather than return codes
C 那種老式的 error code 的寫法已經過時,既然有 exception 可以用,我們當然要用!
- Don’t return and pass Null
只要傳入/回傳 null ,這就意味著其他地方必須要檢查他是不是 null,在 code 非常大量的時候,不停的檢查 *p != null
是一件很煩的事情,乾脆不要傳入/回傳 null 不就好了?
如果真的需要處理這種情況,可以用 Special Case Object ,例如寫一個新的 class 叫 NullMemeber
,負責處理 null 的相關行為,它會自己處理好那些 getter
的回傳值。
Others
遵循 DRY 原則,既然已經寫過,就不再寫一次了,請參考上面的連結。
- Unit test
單元測試很重要,寫專案的時候請務必要寫 unit test,並且對待他們如對待你的其他程式碼一般,Be clean,千萬不要胡亂寫過。
書
其實我最先看的是這一本 Refactoring: Improving the Design of Existing Code,這本書對我幫助很大,它透過很多精簡的例子告訴我怎麼改寫、refactor 會讓 code 可讀性更高,真的是寫程式的人必讀的一本書。
而這本 Clean code,舉例比較沒這麼多,反倒是解釋了一堆實務上碰到的問題,他的例子都是 project 裡會看到的,或許對於職場上工作的人來說更為貼近。此書還有一個章節是 Case study,會解釋它如何改寫一個 Argument Parser
,值得一看。
後記
寫 code 的時候,有時候常常會為求快速,胡亂命名變數、甚至是用骯髒的架構來完成目的,這就是所謂 技術債。當下的確可以讓寫 code 的進度變快沒錯,但過了一段時間,需要修改、審視這段程式碼的時候,就會嘗到苦頭、需要還債了!
我相信大部分的人都有類似經驗,有一段你之前花半個小時寫出來的 parser,變數命名隨便亂取、也沒寫什麼 function。過了幾天你想要再使用這個 parser 的時候,你已經看不懂了…… 因此又再花半小時寫一個。 或是過了幾天這個 parser 需要處理特殊的情況,不過原本 code 的架構已經崩壞,加上其他功能是非常困難的,與其花時間去讀懂並改寫,不如直接重寫。 何苦這樣一直重新製造輪子呢?
當下把程式架構寫好,只需要幾分鐘的時間,但日後若要重新更動架構,那必定需要幾天的時間,因此就索性不做了,於是這個 project 的程式碼品質就會越來越低。
看到不好的變數命名就改掉,架構不合邏輯就改寫,這些小小的修補,在日後一定會有所幫助的。