Dev Talks

加入 5xRuby 團隊後的第一次程式碼審查

5xRuby Technolgy Director QiuZhengXian
蒼時弦也 / 邱政憲, 技術總監 Mar 12, 2021

我們注意到非常多人在前期學習寫程式時,因為沒有養成良好習慣,造成程式碼難以閱讀,或無法釐清邏輯而造成設計缺漏。在開發商業專案時,為後續維護或產品發展造成難以想像的問題。

理想上,我們可以透過 Pair Programming(結隊編程)的方式來輔助。但 Pair Programming 需要更多時間和人力,所以 Code Review(程式碼審查)就是最後一道防線。5xRuby 堅持,所有新進工程師的產出都要經由技術主管或團隊成員進行過一次 review,才能將程式碼提交到專案主線上。

為什麼必須 CODE REVIEW 

是人都會犯錯。為了避免錯誤發生,盡可能多次檢查就十分重要。除了自我檢查,透過他人檢查也有助工程師發現自身盲點。因此,Code review 程式碼審查,不只能讓團隊成員及技術主管審閱產出的程式碼,讓團隊獲得撰寫程式碼、設計架構上的建議,也可針對不符合專案需求之邏輯謬誤、設計問題進行修正。

若再更進一步,則可以利用 Pair Programming 結隊編程來讓審查回饋更即時。Pair Programming 是兩人一組,輪流撰寫程式。能在對方撰寫出有問題的內容時,立即發現並討論改進方式,對新進同事有非常大的幫助。有資深前輩及主管協助,新進同仁得以快速了解公司 coding 習慣及流程,也能針對不清楚之處立即釐清並收到反饋,幫助同仁快速適應環境和改善程式撰寫技巧。

實行程式碼審查也代表公司對程式碼的重視,如同一道美味的料理,從食材選擇起就必須用心對待,我們在將程式碼組合成可使用的功能或軟體前,就會仔細剔除不良部分,盡可能完美規劃。

透過 Code Review 程式碼審查,我們還可以統一工程師撰寫程式碼的習慣,讓程式碼變得更容易維護,更好除錯。以下舉例幾個透過 Code Review 能改善的、看似微小,實則左右專案品質甚巨的問題。

細節藏在魔鬼裡:命名難題

程式撰寫過程中幾個公認最困難的問題之一,就是命名。

大多數工程師應有閱讀過討論 Anti-Pattern(反模式)的文章。文中討論到命名問題時,明白說到應該避免像是 a、b、c 這樣無意義的命名,要用像是 user、cart、line_items 這樣有意義的單字來構成程式碼。這樣除了能幫助其他人理解,在部分語言中,因為語法(Syntax)的特性影響,還能達到 Semantic(語義化)的效果,也就是「閱讀程式碼就像閱讀文章」一樣。

而 Ruby 就是屬於這類語言。舉例來說,我們可以用 refill if bottle.empty? 這樣的方式表示「當瓶子是空的時候重新裝滿」,而這在 Ruby裡 也是一個合法的語法。因此我們在命名上會需要格外小心,像儲存使用者資訊時,我們可能會將「會員等級」的欄位名稱設定為 user_level 儲存在資料庫。而在程式碼實際呼叫時,就會變成 user.user_level 。但實際上在資料的概念中,是「會員」這個實體(Entity)擁有「等級」這個屬性(Attribute),所以我們只需要用 level 去命名,自然而然的就會表現出 user.level 這樣的語法,讓程式碼變得更好讀。

譜出和諧曲調:統一適合團體作業的程式碼風格

一個工程師要融入團隊,就必需面對程式碼風格(Coding Style)風格的問題。

以 C / C++ 這類有大括號語法的語言為例,我們經常會在網路上看到程式碼是要放在括號之後還是下一行的討論。對編譯器來說,兩個做法都正確。因此是否放在下一行,就變成團隊間的約定,這個約定就是程式碼風格。統一風格對新成員如何融入一個團隊,十分重要。

在五倍我們使用 Linter(指檢查語法的工具)來對所有人的程式碼進行檢查。我們使用 Rubocop(Ruby 的語法檢查工具)和 ESLint(JavaScript 的語法檢查工具)來統一撰寫風格,這類語法檢查工具能對應多數狀況,而所餘少數習慣或偏好上的問題則由審查者來確認。

程式碼風格之所以重要,是因為風格會左右閱讀程式碼時的閱讀速度跟理解效率。如果經常在程式碼中使用不規則的語法,或缺少適當換行、空白,都會造成原始碼難以閱讀,也很難推導出專案習慣和偏好來猜測撰寫意圖。

我們也能觀察到, Google、GitHub、Shopify、Airbnb 等國際知名科技公司,都會在網路上公開分享公司的 Linter 設定或風格指南,這樣當公司的開源專案在接受社群貢獻或內部有眾多成員要協作時,能減少溝通成本和人工檢查時間。

成長無止盡:培養持續思考的習慣

對 5xRuby 來說,我們對新人實施程式碼審查,是為了幫助新成員更快速融入公司的開發方式以及文化。也因此,第一次的合併請求(Pull Request)大多會花費一週到兩週的時間調整,在這個過程中我們會去討論命名習慣、程式碼風格以及測試撰寫等議題。透過上述方式,讓新進工程師習慣思考自己的程式碼是否有問題,在命名上是否容易被他人理解、語法使用是否有善用空白、換行幫助閱讀,以及使用統一格式。

接著,他們還需要面對:透過測試確認是否正確理解設計,能對物件行為進行大小適當的單元測試而非大量且需要進行 Mock(製作假方法替代)等設計挑戰。在這過程中,他們能夠學會透過適當的介面設計、單一責任劃分等等技巧,讓物件耦合程度降低且同時保有適當彈性等工夫。

在完成第一次程式碼審查後,即便是新加入 5xRuby 的同學,也能在撰寫程式碼時,學會將程式設計的更加簡潔、優雅,而不僅單純實現功能。我們的專案大多在前期會花非常多心力去準備,並隨著開發歷程不斷改進程式碼,讓我們開發的系統維持在易維護和易修改的狀態,以提供客戶品質更優異、更容易維護的專案。


分享