Clean Code 無瑕的程式碼

什麼是 Clean Code,無瑕的程式碼?又要如何寫出「好」的程式碼呢?

是用更進階的語法?是把程式寫得更加簡潔?還是讓程式跑的更有效率?

這本叫做 Clean Code 的書可以告訴你。

而這系列的文章便是我的 Clean Code 讀書觀後感,除了節錄原書的內容之外,也加上一些我自己在開發中與之對應的心得。

接下來我會以本書章節的順序進行,和你們一起深入學習,如何把程式寫好。

什麼是「好」的程式碼?

先講結論,綜觀本書,我覺得「可讀性」是最最最重要的指標,雖然不完全代表好的程式碼,但卻是不可缺少的性質。

你可能會說,我當然知道可讀性重要,但你或許不知道有那麼重要。作者甚至用了寫散文、寫小說比喻寫程式,要引人入勝,也要字字斟酌。或許不能像是魔戒那麼驚心動魄,但也要讓你的讀者能看得心曠神怡。

One-liner

你有沒有看過把多種操作集結成一行的 One-liner?我在寫 Python 的時候看過許多人追求這樣的極致,感覺寫得越短越厲害。

我節錄了一段出自 LeetCode 的 Two Sum (Discussion Solution),看了這行在 return 後面接著的程式碼後,你能知道做了什麼事嗎?

1
2
3
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
return (c := {}) or (m := next(filter(lambda p: target - p[1] in c or c.setdefault(p[1], p[0]) and False, enumerate(nums))))[0], c[target - m[1]]

看起來很厲害,非常的炫技!或許在解題目的時候不錯,但試想一下,如果你要在某個專案中承接別人留下來的程式碼,修改到這段時,你心中會做何感想?這樣夠簡潔了吧,但不見得好讀。

同理應用在進階的語法和增加提高程式執行的效率上,如果讓整段 Code 變得更好懂,當然是很好的一件事;反之,若讓其變得更晦澀難懂,可能就要思考取捨。

為什麼要寫「好」的程式碼?

如果你也同意好的程式碼要寫的易懂,我們就來看看作者提出例子,說明為何寫「好」的程式碼是一件這麼重要的事。

LeBlanc’s Law

Later equals never

你有沒有因為時間壓力,想著先趕上專案的 Deadline,從而先提交了比較醜的 Code,想著之後再找時間重構的經驗呢?

根據 LeBlanc’s Law 的總結,絕大部分的人現在想的「之後做」,其實就等於「永遠不做」。你真的有回過頭重構之前隨便寫的程式碼嗎?還是就擺著,繼續進行下一個專案了?

態度

作者舉了一個我覺得很有說服力的例子來說明我們該寫 Clean Code 的態度:

許多人會抱怨主管、抱怨客戶 Deadline 壓得太緊,需求一變再變等等,導致沒有足夠的時間把程式碼寫乾淨。但是觀察病人去找醫師問診時,縱使病患是客戶,醫師也不會讓病患想做什麼就做什麼。

原因其實就是,醫師是比病患專業的,比病患自己對他們的疾病有著更全面的瞭解。所以當病患覺得病差不多好了,是不是不用繼續吃藥了?醫師會果斷的說不。

而正在開發的我們這些工程師,對專案的專業程度理論上是比較高的,雖然時程壓力、需求變更肯定是我們會面臨的,但都不是埋下髒 Code 的藉口,否則就稱不上專業了!

閱讀創作比

最後,觀察一下我們看程式碼和實際寫程式碼的時間,根據作者的統計,閱讀和創作的時間比例達到懸殊的 1 : 10!

也就是說如果你一週 40 小時的工作時間,不溝通、不開會、不做其他任何事,只專注在開發寫 Code,實際上可能也只有不到 4 小時的時間真正在打字,其他時間都在看你寫這段 Code 的其他 Code。

那麼當你大部分的時間都在閱讀這些 References 的話,就更該寫的乾淨些、容易理解些了。

如何寫「好」的程式碼?

至於要如何寫出好的程式碼,Clean 的 Code,便是後續章節的主要內容了,包含各式各樣的細節,該做的、不該做的。

但在學習細節之前,可以先看看這條守則,以此當做寫 Clean Code 的態度。

童軍守則

離開時,讓營地比你抵達前更乾淨些

作者引用 The Boy Scouts of America 的這一條守則來譬喻身為工程師的我們寫 Code 的態度。

如果每次開發,尤其時修改既有的程式碼時都比上一次寫的更乾淨一些些,不論是減少一層 if 判斷式、重新命名一個變數都好,那麼整包專案就會變得更好。

參考資料

  1. LeetCode - Two Sum (Discussion)