成為更重視 Code Review 的工程師

Posted by MingLun Allen Wu on Sunday, January 21, 2024

軟體工程師的必修課?

靠寫程式謀生快五年了,常常聽到 Code Review,但從來沒有特別重視這件事情。

三個月前開始擔任 Mentor,需要 Review 新成員的 Code,為了避免誤人子弟,花了不少時間尋找 Code Review 的 Best Practice。

請把它們 (Code Review) 當成是必修課吧,這會讓你成為更稱職的軟體研發工程師。

(從 Code Review 的小事看到大事 - William Yeh)

看到這段文字後,冷汗直流!原來自己一直忽略了 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」,在這個時段進行交流,何謂值得分享呢 ?

  • 結構複雜的變更
  • 極大程度改變團隊生態的功能 (例如團隊共用的框架有新功能)
  • 團隊成員意見矛盾,需要詳細討論

在這個場合,每個成員都能夠針對不懂的內容發問,作者也能針對較複雜的設計進行解說,從而產生的效益包含:

  1. 降低溝通成本,所有成員都看著同一份 Code,降低討論過程中認知不一致的風險。
  2. 知識傳播會自然發生,新舊成員都能從討論中快速釐清不了解的語法、設計。

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 有不同的看法,也歡迎留言交流!

我們下次見。



See Also