軟體工程師的必修課?
靠寫程式謀生快五年了,常常聽到 Code Review,但從來沒有特別重視這件事情。
三個月前開始擔任 Mentor,需要 Review 新成員的 Code,為了避免誤人子弟,花了不少時間尋找 Code Review 的 Best Practice。
請把它們 (Code Review) 當成是必修課吧,這會讓你成為更稱職的軟體研發工程師。
看到這段文字後,冷汗直流!原來自己一直忽略了 Code Review 的重要性。
更嚴重的問題是 : 我該如何開始成為「重視 Code Review 的人」呢? 腦海中頓時產生許多問題 :
- 為什麼要 Code Review ?
- Code Review 就是請其他人來看程式碼嗎 ?
- 我該怎麼請人家 Code Review ?
- 我該如何 Review 別人的 Code ?
好多個為什麼 Orz
為什麼我們該更重視 Code Review ?
探索了一段時間後,我覺得 Code Review 的效益可以從兩個面向討論。
防禦面 - 避免低級錯誤發生
Code Review 是一種 Four-eyes Principle (四眼原則) 的體現。
我認為寫程式有點像是說話,每個人潛意識中會有「習慣的表達方式」,當我們在閱讀這些「理所當然」的內容時,很容易忽略潛在的錯誤。(這一段 Code 不就是這樣嗎 ? 問題不會在這裡出現啦!)
但這時候如果有其他人閱讀,因為習慣不同,反而會一眼看出不合理的段落,能夠避免自己開發時因為「個人習慣」產生的盲點。
如果仔細觀察團隊中的 Code Review,應該會發現一件有趣的事情 : 每個人重視、擅長的面向不盡相同。
審查同樣的一份程式碼,有些人在 Review 時偏重「效能」,但有些人可能重視的是「流程」,每個人關注的面向都不盡相同,這也意味著 : 在 Code Review 時,每個人都能發揮自己的長處,同時藉由他人的長處來彌補自己的漏洞。
同時,對每個團隊成員而言,這也是一個很好的機會去分享「自己對於「好」的定義」,舉例來說:我自己在 Review 時,特別著重程式碼的可讀性,如果過程中有產生訊息,這些內容是否對於使用者友善? 對我來說,這些事情如果做得好,可以大幅降低維運成本。
換言之,當團隊成員皆重視 Code Review 這件事情時,代表的是程式碼的各個面向都會有人替你留意。
當團隊中的每個成員都在 Code Review 時貢獻「好」的定義,這些標準將會漸漸形塑成團隊的「品質標準」,未來在開發時,除了自己的「標準」外,也會開始考量其他成員的「標準」,漸漸的提升整體的產出品質。
積極面 - 提升團隊生產力
從積極面的角度來看,Code Review 有助於提升團隊的生產力。
我在和團隊討論技術相關議題時,常發生一種狀況:在討論太細節的語法或架構時,不論是透過口說、文件、白板呈現,都會因為太抽象,使得有人進入呆滯狀態。
後來的經驗是 : 討論語法時,直接攤開 Code 來釐清現況,最有效!
我目前的團隊會在每週一次的會議中,花 10 ~ 15 分鐘的時間進行「團體 Code Review」,每一位成員可以自己挑選「值得分享的 Pull Request」,在這個時段進行交流,何謂值得分享呢 ?
- 結構複雜的變更
- 極大程度改變團隊生態的功能 (例如團隊共用的框架有新功能)
- 團隊成員意見矛盾,需要詳細討論
在這個場合,每個成員都能夠針對不懂的內容發問,作者也能針對較複雜的設計進行解說,從而產生的效益包含:
- 降低溝通成本,所有成員都看著同一份 Code,降低討論過程中認知不一致的風險。
- 知識傳播會自然發生,新舊成員都能從討論中快速釐清不了解的語法、設計。
Code Review 是 Developer 和 Reviewer 之間的交流
Code Review 其實是一種溝通,由 Developer 和 Reviewer 兩個角色進行互動。
在團隊中,每個成員都有機會成為 Developer / Reviewer,如何在溝通過程中,扮演好自己的角色,同時以同理心去替「對方」著想,我認為是 Code Review 能否順利進行的關鍵。
Developer 可以做什麼 ?
1 - Developer 應該要提供 Reviewer 適當的 Context
過往自己在提交變更時,對於變更的標題、PR Description 常常敷衍了事、隨便亂寫,然後就請其他成員幫我 Review,最常得到兩種回應 : 橡皮圖章般的 Approve (沒有任何回饋,甚至根本沒有看)、石沈大海 (過了一週還是沒人來看)。
為什麼這樣的 Review 請求似乎不容易得到 Reviewer 的關注呢 ?
當 Developer 沒有提供適當的 Context 時,等於是要求 Reviewer 自己扛起找資訊的責任。
為什麼這麼說呢 ? 通常在提交變更時,Developer 應該要提供相關資訊給 Reviewer,例如:
- 此次變更包含了哪些改動?
- 因為遇到什麼問題,所以提出這些變動。
- 此次變動的 Entrypoint 在哪裡?
當 Reviewer 從描述中掌握這些資訊,從某種層面來說,就能夠理解「Developer 寫這段 Code 時在想什麼」,我自己覺得當我站在 Developer 的角度 Review 時,能夠更快的掌握這段 Code 在做什麼,同時也能從自己的角度給予解決問題的建議。
在 Review 其他人的 Code 時,對方是否有提供基本資訊,會極大程度的影響我 Review 的意願,畢竟如果你自己沒有提供資訊,為什麼其他人要投入自己寶貴的開發時間,從你的程式碼中來「解讀」你要做什麼呢?
具體來說,Developer 在提交變更時,應該要包含哪些資訊呢? Google 內部的 Code Review 準則 是個不錯的參考指南。
2 - Developer 應妥善管理 Review 的內容規模
Developer 在請求他人 Review Code 時,需要把這件事對 Reviewer 的「認知負荷」考慮進去。
提交變更時,該如何決定 Pull Request 的範圍 ? 一個獨立且完整(而且巨大)的 Pull Request 比較好,還是數個小型且獨立的 Pull Request 比較好呢 ?
我覺得在工作時,一段「連續的專注時間」是相當稀缺的資源,需要「專注力」、「體力」、「外部干擾」這三件事情同時具備,才可能發生。
當 Developer 提交了一個巨大的變更,需要 Reviewer 花費一小時 Review,此時 Developer 是不能期待馬上獲得回饋的,因為在工作時擁有「完整且不被打擾的一小時」是很不容易的,就算有,為什麼對方要把這個珍貴的時間留給你呢?
相對的,如果將 PR 規模縮小成十五分鐘就能看完,狀況可能就會好多了,因為 「四個專注的 15 分鐘」遠比「一個專注的 60 分鐘」容易取得。
如果希望從 Reviewer 中得到有效的回饋,先試著檢視自己提交的 Code 規模是否恰當吧!
Reviewer 可以做什麼 ?
1 - Code Review 的本質是讓 Codebase 的整體品質越來越好
Reviewer 在進行 Code Review 時,需要將這個大原則謹記在心 :
Code Review 的本質是讓 Codebase 的整體品質越來越好
在 Review 時,是不會有「完全符合自己要求」的變更的!(如果有,那應該是你自己寫的),面對跟自己想法不同的 Code 時,該如何應對呢 ?
只要這段內容有確實提升整體 Codebase 品質,Reviewer 就應該傾向接受。
在遵循這個大原則的前提下,基本上只有當架構或流程有錯誤,或是會影響到其他功能,才會阻止我按下 Approve 按鈕。
但是在 Review 過程中,總是會出現「欸!這功能我覺得可以這樣寫」的時刻,這時候我覺得另外一個建議很受用 : 在 Review 時,可以適當的分級,讓 Developer 能一眼看出哪些評論需要修正、哪些則是單純的建議。
我事先跟團隊成員溝通過,在 Review 中如果看到我用 Nit:
(Nitpick: 吹毛求疵
) 開頭的評論,代表這個評論 Developer 不需要進行對應的修正,通常我會在一些場合使用 :
- 看到陌生的語法,想要詢問作者時
- Coding style 的建議
- 在 Code 中看到其他可發展的功能,想找人討論時
過往在 Review 時,其實只是想拋出某些想法交流,但容易被 Developer 解讀成「雞蛋裡挑骨頭」,是在拖慢開發的進度。
透過適當的分級,能讓 Developer 更明確的掌握後續的修正方式,在不影響到 Developer 的前提下,Code Review 就能成為團隊成員交流程式想法的最佳媒介。
2 - Reviewer 需要特別關注 Response Time 而不是 Review Time
過去在接受到同事的 Code Review 請求時,其實心中默默地將這件事放在很低的順位。
但是在"Speed of Code Reviews“這篇文章中,提到了一個概念:“除非你正專注在某一項特定任務,否則當你收到 Code Review 請求時,應該要在一個工作天內回覆。”
為什麼是一個工作天? 如果在收到 Code Review 請求的當天,工作真的非常忙碌,沒問題,至少在下一個工作天的一開始,Reviewer 可以優先安排 Review。
看到這篇文章時,默默地檢討了自己,當 Reviewer 回應 Code Review 的時間低落時,其實會影響到整個團隊的開發進度。如果換位思考,以 Developer 身份提交的 Code,其實也希望能在最快的時間得到 Reviewer 的回饋。
值得特別注意的是: 要優先關注的應該是 “Response Time” 而不是 “Review Time”。
“Response Time” 意味著回應 Developer 的時間,當 “Response Time” 過長時,容易讓 Developer 無所適從,不知道何時才會得到回饋。如果手邊正在進行重要任務,可以在第一時間告知 Developer : “「Hi,我這陣子有任務在身,可能兩天後才有空 Review,你要不要先找別人?」”
至於 “Review Time” 的長短,我認為更多取決於 Code 的規模,這反倒是 Developer 應該要關注的 (見上節)。
良好的 Code Review 文化 - 站在對方的角度思考
如果我們回顧一下 Developer 和 Reviewer 可以做的事情以及背後的目的:
原則 | 目的 |
---|---|
Developer 應該要提供 Reviewer 適當的 Context | 讓 Reviewer 能掌握基本資訊,專注在 Review Code 即可。 |
Developer 應妥善管理 Review 的內容規模 | 降低 Reviewer 的認知負荷,提升回饋的頻率與品質。 |
Code Review 的本質是讓 Codebase 的整體品質越來越好 | 不做無意義的 Comment,讓 Developer 得到明確的修正方式。 |
Reviewer 需要特別關注 Response Time 而不是 Review Time | 讓 Developer 能快速得到回饋,從而提升團隊的開發效率。 |
看到此處,你可能會有種感覺:
良好的 Code Review 文化,其實跟良好的溝通一樣,Developer 和 Reviewer 之間需要換位思考,替對方多設想一點,就能讓整個協作流程更順暢。
結語
在尋找 Best Practice 的過程中,看到一些很棒的心法,實際套用在工作後,覺得非常有感,希望透過這篇筆記,分享給更多團隊成員。
附上一些在過程中很棒的參考文章 :
謝謝你的閱讀,如果對於 Code Review 有不同的看法,也歡迎留言交流!
我們下次見。