不做代碼審查又怎樣?

從一次回顧會議開始

“要不……我們不做……代碼審查了……試試?”還記得當有人拋出這個建議時周圍同學的表情,那種表情用兩個字加兩個標點符號就可以形容:“什么?!”

對了,先介紹一下背景,這是項目一次普通的回顧會議,我們正在討論的是如何讓代碼審查更有效率和效果。我們做代碼審查的方式比較簡單直接,就是每日站會后,大家圍在一臺開發(fā)機周圍,逐一輪換講解昨天所有提交的內(nèi)容,就像下圖中的那樣。還有,這是一個已經(jīng)超過了7年的比較大型的項目,代碼審查是我們從項目開始就堅持的一個實踐,所以當有人提議廢除它的時候,這在很多同學心里是想都沒想過的事情。

代碼審查是一個很好的實踐,可以幫助團隊里的同學了解其他同學在做什么,可以分享項目的上下文,可以分享技術上的一些小魔法,可以發(fā)現(xiàn)很多潛在的代碼缺陷,可以提高代碼質(zhì)量,還可以有很多很多好處……

但是,在真正的實施過程中,很多情況下并不像想象的那般美好,經(jīng)常出現(xiàn)例如有些同學由于跟不上其他人講解的速度(畢竟不是自己寫的)或是沒有相關的上下文(例如剛加入項目的新成員),或是由于提交沒有被很好的切分和組織,導致整個過程都處于游離狀態(tài)(就像下圖中的我……毫無擺拍痕跡),而代碼審查的效果也打了折扣,漸漸的變成了一個流程,一個過場, 一個習慣。

代碼審查

于是團隊里就有人站了出來,引導大家去發(fā)現(xiàn)背后的問題,也就引來了這樣一場激烈的討論。在討論中,有些同學堅持在說代碼審查還是很有用的,有這樣那樣的好處,需要保持下去;有些同學則非常實際地指出了執(zhí)行上的各種困難和問題。討論異常激烈,直到有人小心翼翼地提出了文章開頭的那個建議,一片嘩然后大家都陷入沉寂:是啊,不做代碼審查了,我們會失去或是得到什么呢?

溝通的收益和成本

在我看來,代碼審查所暴露出的問題本質(zhì)上就是如何權衡溝通的成本和收益的問題

在軟件開發(fā)過程的發(fā)展中,無論是從一開始的瀑布,后來的敏捷,還是當下的精益。都有很大一部分篇幅是在強調(diào)溝通或者說是強調(diào)溝通方式的演進,都是為了解決已有溝通方式所帶來的各種限制和問題。

例如在我們自己的項目中就采用以下的實踐來促進團隊內(nèi)外的溝通,包括:迭代計劃會(Iteration Planning Meeting),每日站會(Daily Standup),代碼評審會(Code Review),回顧會議(Retrospective Meeting);還有XP中的結(jié)對編程(Pair programming),現(xiàn)場客戶 ( On-site Customer )等。

而溝通的好處是可以得到快速的反饋,無論是80年之前就出現(xiàn)的PDCA環(huán)還是前兩年大熱的精益創(chuàng)業(yè),都是在強調(diào)快速反饋和基于反饋的快速迭代,通過這種方式來消除生產(chǎn)和創(chuàng)業(yè)過程中造成的各種浪費。

但是(對,又是但是……),溝通也是有成本的,而且成本一般都還不低,相信這點也不需要多解釋,大家肯定都經(jīng)歷過各種各樣效率極低令人抓狂的討論或是會議。

在溝通的成本和收益同時擺在我們面前,如何做出選擇?如何才能設計一套剛剛好的溝通體系,平衡收益與成本,來滿足團隊和項目的需要呢?

溝通金字塔

在讀《重構(gòu)》的時候,我深深地體會到:這個世界上沒有什么是不變的,包括變化本身。所以要想得到解脫,我們就需要從簡單的對與錯,好與壞的漩渦中跳脫出來,用變化的眼光來看待周圍的事物,并做好一直變化的準備。

而面對溝通成本與收益的選擇困境時,我第一個想到的就是測試金字塔。了解測試金字塔的同學肯定都知道,測試金字塔是一個很好的工具,它幫助我們從單一的測試選擇困境中跳脫出來,將各種不同類型的測試建立起關聯(lián)、納入一個統(tǒng)一的體系,從而讓我們可以在一個更高的維度來系統(tǒng)的思考和審視每一種測試的策略,關注點也從簡單的“該不該”變?yōu)榱恕叭绾巫兓薄?/p>

測試金字塔

至于“如何變化”?我們可以通過在金字塔上添加一層新的測試種類來彌補整體測試策略中粒度太粗的問題;也可以根據(jù)項目情況通過移除一層測試種類,用其上層或是下層的測試來覆蓋其測試用例,來減少成本;也可以通過將某個測試用例在金字塔中向上層或是向下層移動來尋找收益與成本的平衡。

舉個實際點兒的例子,例如我可以將一些基于UI的集成測試用例下移,用成本更低的單元測試來覆蓋從而減少成本,加快反饋速度;也可以將一個單元測試用例上移,用基于UI的測試來增加其穩(wěn)定性的和體現(xiàn)的業(yè)務價值。

看,我們討論的內(nèi)容從簡單的要不要寫UI測試,需要寫多少單元測試測試已經(jīng)被轉(zhuǎn)換到對于整體策略的變化和調(diào)整上來了。那對于代碼審查的問題能否也通過金字塔這個工具轉(zhuǎn)換到更大的空間上尋求突破呢?這就是溝通金字塔。

迭代計劃會

相比于測試金字塔中的“UI--Service--UT,“Iteration Planning Meeting(見上圖)-- Code Review(見上上上圖)-- Pair programming(見下圖)”就可以類比成溝通金字塔,和測試金字塔一樣更靠近金字塔頂端的(例如迭代計劃會)溝通頻率越低,成本越高,但越接近業(yè)務;越靠近金字塔底端的(例如結(jié)對編程)溝通頻率越高,成本越低,越接近實現(xiàn)。這幾種不同的溝通方式所溝通的內(nèi)容肯定也會有所重疊,通過將各個層次的溝通方式進行組合來保證我們團隊的整體溝通質(zhì)量,就像通過金字塔中的各種測試層次的組合來保證產(chǎn)品質(zhì)量的一樣。

結(jié)對編程

如果可以這么類比的話,那我們對于溝通質(zhì)量的管理也應該是動態(tài)的、系統(tǒng)的、從整體上出發(fā)的。例如就可以通過在溝通金字塔中添加一層新的溝通機制來彌補溝通粒度過粗的問題,例如QA Team現(xiàn)在在做的每周例會就是一個好的例子;也可以將一些溝通內(nèi)容通過層次(上下)的調(diào)整,甚至是通過直接減少一層溝通方式來優(yōu)化我們的整體溝通效率,例如我們可以通過增加結(jié)對編程的Switch頻度來替換掉成本更高的代碼審查。而目標就是通過不斷地動態(tài)調(diào)整和優(yōu)化溝通結(jié)構(gòu),試圖尋求一個溝通成本,溝通收益,溝通效率平衡的溝通環(huán)境。

回到問題上來

如果溝通金字塔的理論說的通,那代碼評審就不再是一個:“必須要做的敏捷實踐”,而只是溝通金字塔上的一層而已。那它的存在必然是為了彌補上下層溝通之間的空隙,那這個空隙到底是什么呢?是什么樣的溝通是結(jié)對編程所不能覆蓋,而用類似于迭代計劃會這種更高層的溝通機制覆蓋又不太經(jīng)濟的呢?為了讓團隊重新找回這個答案,我們最終決定試一試:停止代碼審查一個月,在這一個月的時間我們?nèi)ンw會沒有代碼審查的得與失,在一個月之后重新舉行回顧會議再來討論是否要繼續(xù)做代碼審查

在一個月后如期進行的回顧會議上,團隊又重新討論了這個議題,最終覺得通過這一個月的嘗試,在還無法做到更頻繁地Switch Pair的情況下,代碼審查還是很有必要的。例如在這個月中,大家對于其他人在做的工作了解變少,集成出現(xiàn)了很多沖突;缺陷的數(shù)量也有所增加,其中有些是很明顯的錯誤,很容易通過代碼審查的方式發(fā)現(xiàn)并在前期消除;代碼質(zhì)量也有明顯下降,出現(xiàn)了測試的缺失和很多代碼壞味道。

而另一方面為了讓代碼審查能夠真正的發(fā)揮其作用和價值,經(jīng)過討論我們也優(yōu)化了代碼審查的方式,讓大家更有參與感,更有效率,也更有樂趣(見下圖抓拍)。

代碼審查改進版

交付價值 Over 遵循實踐

日本劍道有個心訣,叫守 破 離:
1.“守”:最初階段須遵從老師教誨,認真練習基礎,達到熟練的境界。
2.“破”:基礎熟練后,試著突破原有規(guī)范讓自己得到更高層次的進化。
3.“離”:在更高層次得到新的認識并總結(jié),自創(chuàng)新招數(shù)另辟出新境界。

守固然重要,但如果不能在守得基礎上尋求突破,領會其中的奧秘和背后的道理,則始終無法達到離的新境界。在中國的武術中也有“無招勝有招”的說法,這里的無招就是指在將招數(shù)融會貫通之后,能夠運用招式背后的原理,打破招數(shù)的限制,隨機應變,自由應對。

而反觀我們自己,是不是已經(jīng)慢慢的不知不覺的被困在“守”的圍城之內(nèi),變成了猴子定律中最后的那群猴子,只知道去拿香蕉會被打,也會跟著其他猴子去打那些試圖拿香蕉的新猴子,但是為什么要這么做?我們已經(jīng)忘了,或從來都沒有知道過。

所以,不要以為遵循了敏捷提倡的一些實踐我們就是敏捷的,不要以為遵循了精益的實踐我們就是精益的。在我們沒有理解并追求其背后真正價值的時候,只不過是平添了另外一份成本而已,不如不做。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,678評論 19 139
  • 在上一篇文章中我們討論了你在代碼審查中應該關注的各種內(nèi)容?,F(xiàn)在我們關注一個領域:在測試代碼中關注什么? 本文假設:...
    唐先僧閱讀 2,416評論 0 4
  • 連續(xù)三天的雨天終于結(jié)束了,又出巢嘍,見到美美的陽光啦。每次出來都感受到自己是重獲生命了,但是每一次從屋子里出來都需...
    花開四季的姿態(tài)閱讀 159評論 0 0
  • Swift國內(nèi)社區(qū): SwiftMic Vapor 內(nèi)置支持 Hash 。 示例 想要獲取一個字符串的 Hash ...
    CaryZheng閱讀 649評論 0 1
  • 對于大學生來講,騰訊云是一個很好的福利,但福利也不是這么容易得。 首先要注冊綁定一堆信息,這個信息全部填真實信息就...
    灰羽_閱讀 282評論 1 0

友情鏈接更多精彩內(nèi)容