天天看點

Code Review 常見的5個錯誤模式

專注于為什麼要進行Code Review ,将幫助團隊建立Code Review 流程的最佳實踐,這樣就更容易避免Code Review 的錯誤模式。

原作者:Trisha Gee

Code Review 的時候,每個人都會關心最佳實踐,但最壞的實踐有時可能會更有啟示意義。

Code Review是研發團隊必不可少的,但并不總是正确的。這篇文章指出了所有開發者在Code Review時或送出拉取請求時可能都會遇到的一些常見的錯誤模式,并對這些錯誤模式進行了總結:

錯誤模式:挑毛病

想象一下下面的場景。代碼作者花了幾個小時,甚至幾天的時間來建立他們認為最有效的解決方案。他們考慮了多種設計方案,并選擇了看起來最相關的路徑。他們考慮了現有應用程式的架構,并在适當的地方進行了修改。然後,他們将自己的解決方案以拉動請求的形式送出,或者開始了代Code Review 過程,他們收到的專家回報是:

  • "你應該使用标簽,而不是空格。"
  • "我不喜歡這部分的大括号在哪裡。"
  • "你的檔案末尾沒有空行。"
  • "你們的詞庫是大寫的,應該用句子大寫。"

雖然新的代碼要與現有代碼的風格保持一緻是很重要的,但這些東西幾乎不需要人工稽核員來完成。人工稽核員的成本很高,而且可以完成計算機無法完成的事情。檢查是否符合風格标準是計算機可以輕松完成的事情,這就分散了代碼稽核的真正目的。

如果開發人員在代碼稽核過程中看到很多這樣的注釋,說明這個團隊要麼是沒有風格指南,要麼是有了風格指南,但檢查風格還沒有實作自動化。解決的辦法是使用checkstyle等工具來確定風格指南已經被遵循,或者使用sonarqube來識别常見的品質和安全問題。而不是依靠人工稽核員來警告這類問題,持續內建環境可以做到這一點。

有時,如果沒有代碼指南,或者内部代碼風格随着時間的推移而變化,在不同的部分有不同的風格,那麼這種自動檢查可能會很困難。在這種情況下,有一些方法可以應用自動檢查。例如,一個團隊可以同意做一個單一的送出,應用約定的代碼風格,并且不包含其他的更改。或者一個團隊可以約定,當一個檔案因為bug或功能而被更改時,該檔案也會被更新到新的樣式,而自動工具可以被配置為隻檢查更改過的檔案。

如果一個團隊有多種代碼樣式,而它沒有辦法自動檢查樣式,也容易落入下一個陷阱。

錯誤模式:不一緻的回報

每一個被邀請審閱代碼的開發者,至少要多邀請一個意見,而且可能更多。每個人都可以同時持有不止一種意見。有時,Code Review 可能會陷入審查者之間關于不同方法的争論,比如說是使用流還是經典的for循環最好。如果團隊成員對同一段代碼有不同的意見,那麼開發人員應該如何進行修改,結束審閱,并将代碼推送到生産中?

即使是一個審稿人的想法也很容易發生變化,可能是在一次審稿中,也可能是在一系列的審稿中。在一次審閱中,一個審閱者可能會催促作者確定使用O(1)讀操作的資料結構,而在下一次審閱中,審閱者可能會問為什麼不同的用例會有幾個資料結構,并建議通過單一結構進行線性搜尋來簡化代碼。

當一個團隊對自己的 "最佳實踐 "是什麼樣子的沒有一個明确的想法,當團隊還沒有弄清楚自己的優先級是什麼的時候,這種情況就會出現:

  • 代碼是否應該向着更現代的Java風格發展?還是更重要的是代碼的一緻性,是以,繼續到處使用 "經典 "構造?
  • 在系統的所有部分中,對資料結構進行O(1)讀操作是否重要?還是有些部分的O(n)可以接受?

幾乎所有的設計問題都可以用 "這要看情況 "來回答。為了對答案有一個更好的想法,開發人員需要了解他們的應用和團隊的優先級。

錯誤模式:最後一分鐘的設計變更

開發者在Code Review 過程中最讓人士氣低落的回報是:當評審者從根本上不同意方案的設計或架構,并強行完全重寫代碼時,要麼通過一系列的評審來逐漸完成(見下一節),要麼粗暴地拒絕代碼,讓作者重新開始。

Code Review 不是評審設計的正确時機。如果團隊按照經典的 "網關式 " Code Review ,那麼在最後一步讓另一個開發人員看代碼之前,代碼應該是可以工作的,所有的測試都應該是通過的。在這一點上,幾個小時、幾天,甚至可能是幾周(雖然我真的希望不是幾周;Code Review 應該是小事一樁,但這是另一個話題)的努力已經花在了被審查的代碼上。在Code Review 中指出底層設計是錯誤的,這是在浪費大家的時間。

Code Review 可以作為設計審查,但如果這是Code Review 的意圖,那麼審查應該在實作之初就進行。然後,在開發人員還沒有走得太遠之前,他們可以把自己的想法勾勒出來,也許會有一些存根類和方法,以及一些有意義的名稱和步驟的測試,也許還可以送出一些文字或圖表,以便讓團隊成員對将要采取的方法進行回報。

如果團隊成員在關口審查中發現了真正的展示性設計問題(也就是說,當代碼完成并運作時),團隊應該更新流程,以便更早地定位這些問題。這可能意味着要做其他類型的審查,比如上一段中建議的審查,白闆上的想法,配對程式設計,或者與技術負責人讨論建議的解決方案。在最後的Code Review 中發現設計問題是對開發時間的浪費,也是對代碼作者的極大打擊。

錯誤模式:乒乓球 Reviews

在一個理想的世界裡,作者會送出代碼進行評審,評審人員會提出一些明确的解決方案的意見,作者提出修改建議并重新送出代碼,評審結束,代碼就會被推送。但如果這樣的事情經常發生,誰還能說得清 Code Review 的過程是有道理的呢?

在現實生活中,經常出現的情況是這樣的:

  1. 一個Code Review開始了。
  2. 一些審稿人提出了幾個建議:有的小而容易,有的蓬頭垢面,沒有明顯的解決方案,有的複雜。
  3. 作者做了一些修改:至少是簡單的修改,或者說是幾處修改,力求讓審稿人滿意。作者可能會向審稿人提出問題來澄清一些事情,或者作者可能會提出意見,解釋為什麼沒有做出特定的修改。
  4. 審稿人回來後,接受一些更新,對其他的修改提出進一步的意見,找到他們不喜歡的地方,回答問題,并在審稿中與其他審稿人或作者争論他們的意見。
  5. 代碼作者做更多的修改,增加更多的評論和問題,以此類推。
  6. 審稿人檢查修改,提出更多的意見和建議,以此類推。
  7. 步驟5和6重複進行,或許永遠都是這樣。

在這個過程中,理論上來說,修改和批注應該向着零的方向下降,直到代碼準備好為止。最郁悶的情況是,每一次疊代都會帶來至少和已經結束的舊問題一樣多的新問題。在這種情況下,團隊就進入了 "Code Review 的無限循環"。發生這種情況的原因有很多:

  • 如果審稿人吹毛求疵,如果審稿人給出的回報不一緻,就會出現這種情況。對于陷入這些習慣的審稿人來說,有無限多的問題需要找出,有無限多的意見需要提出。
  • 當審稿時沒有明确的審稿目的,或者審稿時沒有準則可循,就會出現這種情況,因為這樣一來,每個審稿人都會覺得每一個可能出現的問題都必須找出來。
  • 當不清楚審稿人的評論對代碼作者的要求是什麼時就會發生。是不是每一條評論都意味着必須要進行修改?所有的問題是否都暗示着代碼沒有自證,需要改進?還是有些評論僅僅是為了教育代碼作者下一次,而提出問題隻是為了幫助審稿人了解和學習?

評論應該被了解為阻止者或不是阻止者,如果審稿人決定代碼需要修改,他們需要明确說明代碼作者應該采取什麼行動。

同樣重要的是,要明白由誰來決定稽核是否 "完成"。這可以通過任務清單上的檢查項目來實作,也可以由個人授權說 "足夠好 "來完成。通常需要有一個人能夠打破僵局,解決分歧。這個人可能是進階開發人員、上司或者是架構師,甚至是團隊中的代碼作者,因為在團隊中,他們之間的信任度很高。但是,在某些時候,需要有人說 "評審結束了 "或者 "當這些步驟完成後,評審就結束了。"

錯誤模式:幽靈審查

在這裡我承認我最容易犯的反常的地方:幽靈化。無論我是審閱者還是代碼作者,在代碼審閱中都會出現一個點(有時就在開始的時候!),在審閱過程中,我根本就沒有回應。也許有一個重要或有趣的功能被要求我審閱,是以我決定把它留到 "更好的時候",等我可以 "真正好好看一看 "的時候再做。又或許是Review的量大,我想留出充足的時間。又或許是我是作者,在疊代(或二十次)後,我就是無法面對閱讀和回複評論了,是以我決定等 "等我的腦袋想好了再來"。

聽起來是不是很熟悉?

不管是什麼原因,有時在審查過程中有人根本沒有反應。這可能意味着在這個人看完代碼之前,審查工作就已經死氣沉沉了。這是一種浪費。即使有人在建立一個資産(新代碼)上投入了時間,但在它投入生産之前,它并沒有增加價值。事實上,當它在代碼庫中越來越落後于其他代碼庫的時候,它很可能已經腐爛了。

有幾個因素會導緻幽靈審查。龐大的代碼稽核量是一個因素,因為誰願意去翻閱幾十個或幾百個修改過的檔案?不重視Code Review 是另一個因素,因為不重視Code Review 是真正的工作或傳遞成果的一部分。困難的或令人沮喪的Code Review 經曆是另一個主要因素。沒有人願意停止編碼(開發人員通常喜歡的東西),去參加一項耗費時間和破壞靈魂的活動。

以下是解決幽靈審查的建議:

  • 確定Code Review 的規模要小。每個團隊都要制定出自己的定義,但這将是幾個小時或幾天的複審工作,而不是幾周的時間。
  • 確定Code Review 的目的很明确,審查人員應該找的東西很清楚。當範圍是 "找到代碼中可能存在的任何問題 "時,很難激勵自己去做一件事。"
  • 在開發過程中留出時間來做Code Review 。

最後一點可能需要團隊的紀律性,或者團隊可能希望通過(例如)通過目标或任何用來決定開發人員的生産力的機制來獎勵良好的Code Review 行為來鼓勵允許時間。

你的團隊能做什麼?

對于研發團隊,專注于建立一個行之有效的Code Review流程。我在我的部落格上寫過這方面的内容,但想在這裡分享一下這個過程的一部分:

  • 在進行Code Review 時,有很多事情需要考慮,如果開發人員在每次Code Review 時都擔心所有的事情,那麼任何代碼都幾乎不可能通過評審流程。要實作一個适合所有人的Code Review 流程,最好的方法是考慮以下問題。
  • 團隊為什麼要做審閱?當有一個明确的目的時,審查員的工作會更容易,代碼作者也會從審查過程中減少讨厭的驚喜。
  • 團隊成員要找的是什麼?當有了目的,開發人員可以在審閱代碼時建立一套更有針對性的東西來檢查。
  • 誰來參與?誰來做評審,誰負責解決意見沖突,誰最終決定代碼是否合格?
  • 團隊何時進行複審,複審何時完成?稽核可以在開發人員在代碼工作的時候疊代進行,也可以在流程結束時進行。如果沒有明确的指導,一個評審可能會一直進行下去,如果沒有明确的指導,代碼最終什麼時候可以進行。
  • 團隊在哪裡做評審?Code Review 不需要特定的工具,是以審查可能就像作者在辦公桌上帶領同僚看他們的代碼一樣簡單。

一旦回答了這些問題,你的團隊就應該能夠建立一個運作良好的Code Review 流程。記住:Code Review 的目的應該是讓代碼投入生産,而不是證明開發人員有多聰明。

結論

Code Review 的錯誤模式可以通過建立一個明确的Code Review 流程來消除,或者至少是緩解。許多團隊認為他們應該進行Code Review ,但他們沒有明确的準則,為什麼要進行Code Review 。

不同的團隊需要不同類型的Code Review ,就像不同的應用程式有不同的業務和性能要求一樣。第一步是弄清楚團隊為什麼需要審閱代碼,然後團隊就可以着手于:

  • 自動化的簡易檢查(例如,檢查代碼樣式,識别常見的BUG,發現安全問題)。
  • 就審查的時間、審查的内容以及審查結束後由誰決定等問題制定明确的準則
  • 将Code Review 作為開發過程的一個關鍵工作内容

原文:https://blogs.oracle.com/javamagazine/five-code-review-antipatterns

關注公衆号:架構未來 ,我們一起學習成長

Code Review 常見的5個錯誤模式

繼續閱讀