我知道我已經提過太多次變數名稱要具有表達性────雖然那其實不是我提的而是作者────但我這裡要說的,不是指這件事。
讓程式可讀性提昇的最有效方式之一,是將計算過程拆解成許多富有意義名稱的暫存變數。
我們很多時候想簡化程式碼,所以選擇用一行敘述來完成功能,這樣的程式確實看似緊實、簡單,然而卻不容易被閱讀及理解。讓我們來看一段來自 FitNesse 的範例:
Matcher match = headerPattern.matcher(line);
if(match.find()){
String key = match.group(1);
String value = match.group(2);
headers.put(key.toLowerCase(), value);
}
我們可以看到,這個例子中的運算過程被拆分開來,其值分別放入了具解釋性的暫存變數中。於是我們可以很簡單地了解到,第一個比對到的群組是代表鍵值 (key) ,而第二個比對到的群組則是數值 (value) 。一般來說,具解釋性的變數越多越好,這些中繼變數將能使程式的可讀性大幅提升。
當我剛開始學習 CSS 的時候,有一次同學所做的畫面不如預期,於是來請教說是怎麼回事。我看了她所寫的內容後,問了關於幾個地方她這樣寫的原因,而她表示:「我也不知道,試出來這樣寫的畫面是我要的。」當下我感到些許吃驚,跟她說還是要去弄明白這些語法的意義跟效果會比較好。
而如今,我們有時候寫程式的時候也是這樣,只是很努力地讓功能被實現,但卻無法也無心去了解那一整大塊的複雜邏輯。它通過了測試,所以我們知道它能夠運作,這沒有不對。但不夠。
因為許多人並沒有花時間去了解演算法,以至於產生許多可笑的程式碼。他們透過加入足夠的 if 敘述和旗標來讓程式能夠運作,而沒有停下來,仔細思索這裡的演算法在做些什麼。
而要瞭解演算法,最好的方式就是對函式進行重構,使它的組織變得明確,程式具被表達力,能夠明顯地說明該段演算法是如何運作的。事實上,我認為重構使程式具表達力,也是之所以我們要足夠了解它的原因。
當我們在撰寫程式碼時,要思考這個決定是否足夠精確,避免在精度上偷懶。
期待第一個比對成功的物件就是我們所要查找的結果,是天真的預設;使用浮點數來計算貨幣,可能下半輩子都要準備去還債;可以使用 List 就足夠的情境卻使用 ArrayList,是過度限制;所有變數都使用預設的 protected,是保護不足。
不精確的程式碼,往往是由懶惰所造成的,我們應該極力避免,就像我們不該因為貪圖方便而無視安全規範一樣。