Nic Lin's Blog

喜歡在地上滾的工程師

如何提升你的程式可讀性之實務技巧(一)

有沒有遇過一種情況是,即使需求不是這麼急迫,團隊之中總有習慣了問題來隨手就解的隊友,那個神來一筆的 commit 也跟著埋下了考古的鑰匙。

直到要維護時,你才發現你就是這個考古學家,戴上帽子拿起放大鏡,要來探索這看似熟悉卻陌生的語言。

「咦,這些簡寫是什麼意思?」

「這個 function 命名跟行為怎麼不一樣?」

「status == 5 是指什麼啊?」

於是你帶著各種疑問繼續在迷宮打轉,此時多希望有翻譯蒟蒻。

也許,我們都應該多在乎一點別人,在每次 commit 後,檢討一下這次提交內容的可讀性,是否能夠輕易被理解?

這篇文章主要會和大家分享,在過去的開發歷程以來,和非常厲害/困擾的高手合作後,整理出這些對我或團隊來說能夠提升「可讀性」的方法,而這些技巧方法也直到現在都還在使用。

文章的篇幅主要會分成三個部分

  1. 提升可讀性能夠帶來的實際幫助 <- 本篇
  2. 以程式碼示範提升可讀性好用的技巧
  3. 以測試、開源等不同角度去提升可讀性的方法

在程式碼範例的部分,主要會以 Ruby / JavaScript 的語法作為示範,其寫法盡可能會寫的繁瑣一些,其目的是希望能夠讓其他語言的學習者也能夠理解。

  1. 提升可讀性能夠帶來的幫助
    • 這篇文章會寫什麼?
    • 你知道國語和國文的差別嗎?
    • 可讀性帶來什麼幫助
  2. 用實際開發案例說明提升可讀性好用的技巧
    • 觀念
    • 命名
    • 註解
    • 流程
  3. 以測試、開源等不同角度去提升可讀性的方法
    • 性能與可讀性
    • 約定優於配置
    • 社群規範 Ecosystem
    • 以測試角度提升你的可讀性
    • 總結

這篇文章會寫什麼?

我們都知道,網路上有很多文章分享程式碼如何改善可讀性,甚至會推薦你去看 Clean code / The Art of Readable Code / Implementation Patterns,等等一些文章筆記或書籍。

懶的人也可以在網路上找到別人消化過的筆記文章。

但看完這些文字後,對於實務上還是不清楚怎麼改善,也不曉得可讀性這種抽象的標準到底在哪裡,畢竟好不好理解,是相對主觀的。

以 Kent Beck 所寫的 Implementation Patterns 一書,其內容提到了 77 個實作的 patterns,這概念又與 Clean code 所提到的不完全相同,只能說對於軟體開發的設計模式,各自有不同的見解。

但能夠讓程式碼可以在開發時具有「溝通」的效果,卻是一致的目標,所以這篇文章主要會和你分享,在程式撰寫時,可讀性的重要及如何透過一些簡單的觀念來建立並提昇自己,加強自己在撰寫能力上的內功心法。

這些方法是我自己整理出來比較常見,可以快速調整方向或思維的作法。

有趣的是,我在過去一年裡,同時寫了 Ruby / Go / React Native 的專案,在以下的範例內容,我會盡可能以簡單的變數命名、變數命名、function 來作為表達,想和你分享的是,可讀性的基本功夫是可以貫穿程式語言的。

你知道國語和國文的差別嗎?

在程式開發中,良好的可讀性必然是系統健全體質的重要指標之一,這個指標能夠如何幫助我們提升開發效率及品質呢?

有多少次,我們聽見「之後在改」,但往往事實是將這段程式碼放置到遙遙無期封塵已久,直到回首時,才發現這個撰寫的時日已經是一年前了。

其實更常發生的情況是,常常覺得不可置信,卻也不可否認的情況,就是這個程式碼你只會寫這麼「一次」,一時貪快而未曾深思的你選擇了 work/hack around 的做法,雖然能夠解決當下的問題,但也同時為未來的自己或他人埋下迷宮的關卡。

或許你會說,現在很急著要上、老闆明天就要、公司我最資深啊,以及各種不可抗拒的理由,所以你被時程逼迫寫下可讀性可能不是太好的程式。

但我們換個角度仔細想想,如果有一場 50 分鐘的演講你即將上台,但主辦方臨時將時間更改成只有 10 分鐘,那麼你說話的方式、語句會從口齒清晰變成含糊不清嗎?

通常不會。

因為你已經習慣你的說話方式,或許這個改變讓時間變的有限,內容也被侷限,但你能說出的內容取決於你的內涵及所學,並不會差太多的,因為表達方式已經內化到你的大腦裡了,也就像是武俠小說所說的內功。

為什麼我們小時候在上課的過程中,國小學習的是「國語」,而到國中之後變成「國文」

因為這是兩個完全不同的領域

  • 國語: 讓你認識基本單字、字詞及基本用法
  • 國文: 讓你學習文字的運用,各種句子、形容來完整表達自己的想法。

所以當你學會了程式語言中的 if else / loop / API,那就像是學習「國語」,也就是所謂基礎用法,你明白程式可以透過參數傳遞、條件判斷,來達到不同的執行結果。

而將想法轉成程式碼時,如果沒有學好「國文」,自然容易寫出不具可讀性的程式碼,再加上我們的母語並不是英文,對很多人而言,只把程式語言的英文當做積木來拼湊,而不是把他當一個句子或文章來看待。

所以當把「國文」學好時,時間久而久之會內化成你的功力,我認為就算環境在嚴苛、時間再急迫,也可能因為這些情況有實作方法上的 trade off,但這時的你應當能隨手寫出「至少」能讀的程式碼了。

舉個例子,如果你習慣命名 latestPosts,不會因為時間很趕就變成 lps,因為根本不差這幾秒鐘啊

業餘跟職業的選手差別在於,職業選手透過長久的練習及內化,能夠不透過思考直接反射性的使出高階招式。

這對選手來說,是境界的不同,對工程師來說,何嘗又不是如此呢?

可讀性帶來什麼幫助

提升效率

在寫程式碼時,總是很難在第一時間就「完全正確」,所以或多或少會有除錯的時間,難以閱讀的程式碼就像是一座迷宮,不僅迷惑了自己還會讓協作者花更多時間去理解。

或許你有高超的記憶力,能夠很快的從迷宮逃脫,但通常一段時日過後回頭來修改維護時,會重新挑戰你的記憶力,不易讀懂得程式碼將會再度浪費你的開發時間。

所以,可讀性提升的是未來自己和他人的開發效率

減少犯錯

良好的可讀性也就意味著表達明確,而不是曖昧不清或隱諱的敘述。

當一段程式碼的命名敘述不同於執行內容時。

在現實生活中你會說這產品廣告不實、在機場海關這叫偷渡、在女生嘴裡叫口是心非,但在開發程式時卻叫他媽的誰放的地雷。

我們來看以下的例子

def increase_read_count(post)
  post.update(read_count: post.read_count + 1)
  SendEmail.perform(post)

  return post
end

我們以為 increase 會如同字面上的意思只是單純增加計數,但如果沒仔細去看實作細節,他竟然還會偷發一個不知道做什麼用的 Email,這就屬於一種隱諱的寫法,因為和主要敘述功能的名稱不完全符合,也難以聯想。

所以,明確的表達能夠減少犯錯

幫助他人學習

可讀性高的程式碼,能夠讓人更快進入狀況,瞭解其邏輯、設計架構,而減少時間在搞懂這迷宮到底怎麼蓋的,能夠展現其思緒及脈絡。

不論對於他人學習或團隊合作都有很好的幫助,以 clean code 的名言來說,也就是

當每個你看到的程式,執行結果都與你想得差不多,你會察覺到你正工作在 Clean Code 上

所以,可讀性能夠幫助他人和自己更快學習

小結

在接下來的章節,會以程式碼的實際案例來和你分享如何透過思路上的調整,去提升可讀性。

請繼續閱讀下一篇章。

本系列其他文章

comments powered by Disqus