今天當你的 code 寫完自己測試完後,是不是下一步就要直接部署到 production server 了,well not yet,現在軟體開發流程中,尤其比較成熟的團隊裡,通常都會有一個環節叫做 code review,主要目的很簡單就是請其他人看看你寫的 code 看哪裡可以怎麼寫比較好、有沒有 follow 公司的 convention、哪邊可能會影響效能或是報錯等等,最早的 code review 文化應該是 1976 年有位 IBM 工程師叫 Michael Fagan 發表一篇論文叫 Design and Code Inspections to Reduce Errors in Program Development,不過這邊他用的字是 inspection 而不是 review 比較像是檢查或偵查的感覺,coder 隨機找一個人來讀他的 code 然後找錯誤,這麼做的目的就是希望在開發早期時間充裕情況下可以抓到錯誤而不是部署到 production 了再處理,之後到了現代配合 git 這個工具和 git workflow 請別人 review 完 code 就可以把我們的 PR merge 了。根據公司文化不同,code review 的形式也有很多種,有那種把大家叫過來開個 meeting 大家看你的 PR ,我自己第一次聽到時候覺得很 unbelievable 因為這樣其實效率很差而且這就會回到那個最重要的問題:這有必要開會嗎?現在最常見的還是配合 git 這類的 version control 來寫 PR reviews 或是 review 完直接 merge,另外一種雖然不太像是 review 但也會確定你的 code 被多人思考過就是 pair programming,畢竟 code review 其中一個目的是確保 code 被其他人確認過有沒有 cover 到 edge case 或是寫 code 的人沒有想到的事情而 pair programming 會在討論過程中 cover 這些 use case 我希望是有啦。
Code review 這個流程帶來的好處除了剛才提到的提高 code 的品質和抓出有沒有 anti-pattern,我們會希望能在早期抓出這些錯誤和以防不必要的 technical debts,假如我們寫的 code 沒有人 review 而剛好到最後 production 才發現有 error 或是一些本來沒有想到的事情,到時候得 roll back 或是在當下把解答想出來是很有壓力的,加上公司有 deadline miss 掉上線時間可能也不好看,雖然不是說有 code review 肯定能抓到但至少多一個人幫忙看多一點機會,也多一個人來熟悉你的 feature 和你的 code。code review 同時間也可以作為 mentoring 的工具畢竟我們會在上面留 review 和討論的過程而這些紀錄都是可以讓 junior 或是新人學習的材料,有 code 直接做 reference 而且也看得到一個 PR 的歷史紀錄對任何工程師都是好的。
當我們需要請其他人 review 我們的 code 時候我們也需要做些準備來讓整個動作變得更流暢更簡單,前面提到現在的 code review 通常會在類似 github 這類工具上面操作,每個人的 git workflow 不同但大致上大概是為了自己的 feature 或 bug fix 開一個新的 branch,等我們確定做好了寫完測試了我們會開 PR 然後邀請其他工程師做 code review,首先我們能做的是在 PR 裡面大概寫一下這個 PR 是做什麼的,有些會直接貼 Jira ticket 連結或是把 commit 接到 Jira ticket 都可以,就是要給 reviewer context 說這個 PR 開出來的目的和要達成的效果是什麼,再來可以的話貼一個 demo video 讓他們知道一下成果出來的樣子讓他們看一眼可以知道這個 PR 完成了什麼,有些公司有相對應的 infra 可以透過 CICD 起一個 review server 這樣可以直接透過連結看那個 PR 而不用再自己 local switch branch 起 local server,最後確保你的 PR 不要太大要不然 review 起來會很辛苦而且非常花時間,個人通常控制在 10 個檔案一下,20 個以上就有點大了,我們做的這些都是為了確保 PR review 可以很順的執行也減去很多溝通的成本和減少 friction。那身為 reviewer 的人我們只要要做的就是看看有什麼地方可以進步修改,我們可以從一些角度切入比如:readability 可讀性,這些 code 能不能讓工程師清楚理解是做什麼用的,這些 variable 和 function 名字是不是合理的,如果 algorithm 不好理解是不是有相對應的 comments 來做補充;reusabilty 能不能被重複利用或是需不需要拿已經有的 function 或 components 來改,這也牽涉到之後這些 code 能不能簡單的被發現也幫助之後其他的 project 能不能很快的利用這些寫好的 functions 來開發下一個 feature,省時間也省精力;其他比如效能和安全性,我們不希望寫出一個 function 是會把整個 application CPU 拉高最後直接當機的或是整體感覺太慢給使用者體驗很差最後沒有人下單買你們公司的產品。其他我們也會 care 比如要空格 4 個 spaces 或是 import 的順序是什麼但這些都可以透過 linter 和 prettier 及其它工具來達到利用 CI 自動化這樣人工 review 只需要 focus 在最重要的東西上面。
我們寫 review comment 也是一門學問,畢竟文字是沒有溫度的不太容易感覺到講這句話時候背後的情緒是什麼,有些句子因為我們理解這個人所以聽起來是開玩笑但不熟悉的人會覺得被嗆,所以我們盡量用比較正面的文字和句子來表達自己的意見和提醒對方是不是有想到其他 potential problems,我們可能會說我覺得這些 logic 可以拿出來寫成一個 hook 你覺得呢?或是這個 library 有個 API 可以代替你寫的而網址在這邊,我們要試著給有建設性的 feedback 或是別人聽了可以執行的 fedback 而不要那種講完就過對方也不知道接下來要做什麼或是怎麼討論,還有我們也要小心不要變成雞蛋裡挑骨頭變成一定要聽你的這樣就是所謂的 nitpick,比如你覺得這個 function 讀起來應該把原本的 function name 改成另一個但原本的也不會影響什麼只是稍微比較好或是看的比較順眼就可以 nitpick,但要小心說不要變成只是在噹別人的 code 就不好了而且這樣雙方也學不到東西。
這類的文化和 practice 對任何工程師應該都是好的,用大家的力量把這個 project 做到好,讓大家學習怎麼給 feedback 也可以在公司或 open source project 透過這樣的方式讓雙方進步然後把 domain knowledge 傳授給其他人,那我知道在台灣很多人所謂的一條龍一人前端一人後端不太能透過 code review 的形式來進步都是寫好直接 commit 到 main branch,可以從外部找人試著做 pair programming 才能發覺自己沒注意到的東西或是找找有興趣的 open source project 來 contribute 這樣就一定會有 code review 的流程。