codereview(CR)一直以來在軟件行業被視爲提高代碼質量的一種有效的方式,也被視爲一種工程師文化的表明。關於什麼是CR,在goole出具體的定義以下:html
代碼評審是指在軟件開發過程當中,對源代碼的系統性。一般的目的是查找系統缺陷,保證軟件整體質量和提升開發者自身水平。 Code Review是輕量級代碼評審,相對於正式代碼評審,輕量級代碼評審所須要的各類成本要明顯低的多,若是流程正確,它能夠起到更加積極的效果。正因如此,輕量級代碼評審常常性得被引入到軟件開發過程當中。java
從上面的解釋中能夠基本上能夠看出CR的幾個核心關鍵點:git
能夠發現,CR在研發流程中若是合適的引入進來,無疑會大大加強系統的代碼質量,促進團隊的的發展。但同時,也須要一塊兒根據團隊的現實,去因地制宜肯定方案。程序員
關於爲何要引入CR,我也一直在想這個問題,推行CR的最大的阻力無外乎在於流程的執行須要時間落地,而這部分流程也必定會很重,必定須要團隊在時間上願意爲引入這個流程進行買單。除此以外,不合適的CR方式也必定會形成不少負面的影響:github
A:這段代碼須要在這裏,這裏,還有那裏進行改動;算法
B:LZ代碼明明質量很好了,you can you up, no can no bbshell
A:這段代碼你必定要改;編程
B:內心很複雜,思想上很累設計模式
若是CR執行的流程不對,必定會出現這種狀況,若是一旦出現這種狀況,CR的推行必然就是會失敗的,嚴重的話會損傷小夥伴感情,同時會影響團隊的開發氛圍,但我以爲,出現這種狀況,有個根本的緣由在於CR流程上在每一個階段上彙集的點不同形成的,通俗的來講,就是你在說A,TA在說B,如何解決這樣的問題,個人思考會在下面給出。緩存
固然關於,CR的引入帶來的負面影響應該還有不少。可是,CR會帶來哪些收益呢?應該隨便列舉下就會有這麼幾點:
提高代碼質量
這一點很重要,在what部分已經闡述,無需再贅述;
有利於規範的落地
在Java上有開發規約,可是沒法避免的有些仍是沒有落地遵照,很大一個緣由仍是每一個開發者對開發規約記住部分或者理解的部分在認知層面是不一樣的,好比有的人可能只對5條理解很透傳,而有的人可能理解8條。若是有CR,開發者會有碰撞溝通的機會,就算5+8不能等於13,可以5+8=10的話,對每個人就都是10了,而不是5和8,這個收益是巨大的。那麼,對團隊而言,規範是真的落地了。同理,JAVA開發規約須要通用性,面對的是大多數開發者,而每一個團隊會根據本身的業務場景和團隊現狀制定相應的開發規約,而這部分落地也須要CR去承載,同上面的分析同樣,每一個人在認知結構上會ownner一部分,再拿出來進行交流,無疑會加速規範的落地;
對業務的理解加深
若是是正式的CR(round code-review),即小圓桌CR,會有多個開發者一塊兒參與的CR,必不可少的就會有代碼走讀,那麼走讀代碼的時候,天然而然會闡述出本身對業務的理解和當前的業務流程,我一直相信,看讀寫是對一件事情不一樣理解程度的進階,咱們會根據當前業務編寫代碼,可是若是咱們在走讀代碼的時候可以按照本身的理解講出來,對本身而言收穫會更大。除此以外,參與到CR也能從中知道其餘業務其餘同窗對其的思考和編碼設計,是一個巨大的學習機會。咱們總會有這樣的焦慮,總感受本身每次作的是一個xxx模塊,對總體缺少理解,感受本身永遠就是一個碼農,我想若是有這樣的機會,對系統和業務總體的感知會增強,若是一個開發團隊都是一個全能戰士,這樣的戰鬥力是巨大的。
表達溝通能力的加強
CR是多名開發者參與協同的過程,在代碼走讀過程當中,自身的表達能力確定會獲得鍛鍊,咱們會思考如何準確而清晰的向其餘人表達我當前的設計以及當前所要解決的業務問題。同時,當迎來挑戰時,如何向挑戰者解釋當前的邏輯和思考,若是挑戰者更加有理,如何有一種欣然接受並表示對提出者表達感謝這樣一種高情商的表現。
向前輩學習的機會
在工做中,新人總想向前輩學習經驗,礙於平時總沒有合適的問題場景,有時候去詢問前輩也只能停留在表面上的交流,沒法針對具體問題場景進行深刻分析。CR就是一個很好的機會,產生分歧的時候就是一個具體的問題場景,新人能夠就這個場景向前輩們學習他們的設計思考,以及他們的解,點滴的積累,對新人來講無疑會產生質變,對團隊而言,老帶新在無形之間就完成了傳承。因此,CR是一個具體而實在的學習機會,我迫切的向前輩們學習他們的經驗和設計方法,也是我強力想落地CR的一個動機。
儀式感
生活中須要儀式感,咱們會有各類記念日,以告訴咱們本身生活的甜。一樣的,在工程師文化中我也認爲CR是一件有儀式感的事情,開發者在一塊兒集思廣益,本就是一件很幸福的事情,並僅僅只是由於對工程師文化的信仰促成了這件事情。
以上是本身認爲CR可以帶來的優勢,也是我認爲CR若是落地會帶來的收益巨大。若是真要解釋why—爲何要引入CR這個問題,無外乎就是須要回答CR能給團隊帶來什麼:
找到問題,永遠只是CR的副產品!
大多數狀況下,找問題會是CodeReview活動啓動的初衷,但越到後期它更大的意義將演變成工程師交流土壤的培育和人員成長的促進。但通常來講,不少團隊在CodeReview前期重點會是找問題(代碼規範、潛在缺陷、BUG,代碼設計等等),而後期隨着問題的逐漸減小和習慣的逐步養成,工程師交流文化的營造將轉化成重點,中期當有大批新人加入時,找到問題將又上升爲重點,如此復始。
CodeReview最終的做用將歸到促進工程師平常代碼交流和人員的成長上面來,與此同時做爲輔助手段來對產品質量進行把關。
CR是一項協同活動,在推行CR以前,也須要明確參與到CR的主體。CR這項活跟團隊狀態、團隊技術信仰以及團隊訴求有關,因爲與」人「掛鉤也必不可少跟」人「這個因素有關,固然必不可少的還有代碼和參與這項活動的各我的員。
團隊花精力引入CR天然而然是期待這種輔助手段以解決某些問題,也就是說當前團隊但願藉助CR以實現進階突破,那麼下面幾種團隊類型有必要引入CR:
那麼什麼樣的團隊不須要引入CR呢?
CR的另外一個主體確定是代碼,也是開發者討論的主體對象,是否是全部的代碼都須要引入CR,個人觀點是沒必要的。
核心鏈路業務代碼
在複雜的業務場景下,承擔主要的業務功能的代碼須要拿出來CR,那麼如何來衡量哪一個部分是核心鏈路呢?從業務流量分佈上來看,在互聯網應用中有28原則,即80%流量在20%的數據(業務)中,那麼這20%的業務代碼就是須要拿出來CR的,這部分代碼承擔了本次迭代核心功能,也是用戶最爲care的點,同時也是本次軟件業務週期中聚焦點,也是PD的強功能性需求,天然而然也是須要被格外重視的地方,若是存在線上風險,損失是巨大的。
系統底層框架核心代碼
從系統的基礎建設角度來看,PD的需求通常是功能性需求,無暇顧及到系統的非功能性需求,這部分是開發者賦予系統的健壯性,而這部分關乎到軟件系統是否可以提供強健的生命力,也被視爲系統的引擎。舉例來講,在協同平臺項目管理三期項目—里程碑規範中,經過里程碑模板建立里程碑以及里程碑時序規則校驗機制,就被視爲這期項目的」基礎建設「,理所固然也應該被拿出來CR,若是存在問題,必將」風雨襲來,大廈將傾「!
事實上,以上兩種類型的代碼在技術方案評審就能夠被肯定下來,並須要進行round CR進行。
業務直譯式代碼
參照流量分佈,總有一部分業務功能並不是用戶關心的核心功能,只是由於系統功能完整性而存在,或者業務流程很簡單,從controller-->service-->dao參照PRD」翻譯式「編寫的代碼(稱之爲業務直譯式代碼),客觀來講並不須要花費長時間進行round CR。可是不是就必定不須要CR呢?也是未必的,只是流程就不須要那麼重,能夠採用deskmate CR(即同桌間進行溝通),也就是peer programmer(結對編程),兩人進行簡單高效的溝通便可。
CR終究是一件與人相關的活動,而且CR的質量也跟人之間溝通協做效率掛鉤。所以,要想得到高質量的CR,就須要理清CR中參與的人員角色,並賦予相應的職責。
主講人(speaker)
speaker即爲當前走讀代碼的開發者,我更願意將其稱之爲speaker,而不是被review的人。speaker是出如今學術會議以及各類技術會議上,宣講本身的思想和概念的人。我也認爲,每個走讀代碼的人,應該抱有這份自信,去向其餘開發者合理清晰且邏輯清晰的表達本身的觀點,若是本身都不能很自信,如何去說服其餘人呢,代碼應該是開發者的藝術品。因此,對speaker來講有如下職責:
reviewers
reviewers是指對開發者代碼提出建議的人,在這裏角色中也可被拆分紅兩類角色:
reviewer-ownner
這個角色被認爲是對當前系統最爲熟悉的人,能夠說是當前系統的建立人,熟悉系統的各處神經脈絡。所以在reviewer時,須要觀察當前開發者的代碼是否會傷害已有的架構。除此以外,這種角色也應該具有業務的感知能力,除了完成當前需求外,憑藉其自身的業務感知能力,應該對當前系統功能走向有所預測,須要判斷當前開發者的代碼可以對將來的業務有擴展性和支撐性。這類角色,遵照的基本原則是」大處着眼「。
reviewer-expert
事實上,在reviewer-ownner這類角色中基本上已經不是一線開發者,在CR中確定須要經驗豐富的開發者,而這個角色基本上在CR過程當中,憑藉其自身的經驗會對開發者代碼就具體的點提供細緻的建議,而這些建議就是推進團隊代碼規範以及質量的關鍵要素,這類角色,遵照的基本原則是」小處着手「。
那麼針對這類角色應盡的職責有哪些呢?
recorder
在CR的過程當中,理所固然須要記錄後續的action,也就是說須要這麼一個角色負責這個事情。單獨須要這麼一個角色在於speaker和reviewer在CR過程當中須要進行溝通表達,若是停下來來記錄,分散其注意力,整個過程每每就不會一鼓作氣,會大大損失CR的快感。那麼對這類角色有以下職責:
以上四個角色會存在在CR過程當中,但四個角色並不必定就是多我的,每個只負責一個角色。也有多是一我的,負責多個角色,好比結對編程中每每只有兩個角色,那麼這個speaker又要負責代碼的走讀以及做爲recorder進行記錄。對角色責任範圍必定要理清,否則在CR過程當中就是無頭蒼蠅,找不到發力點。
CR能夠是一個在很是正式的會議室舉行,也能夠是在同桌同事間進行,也就是說根據CR進行的場所的能夠對CR進行分類,實際上,這種分類也從側面反映出不一樣的業務場景應該選擇什麼樣的CR形式,在這篇文章中將CR進行了分類,我對其進行總結概括:
- 同桌(deskmate-CR),也稱爲結對編程(pair programming):同桌間就一個問題互相討論
- 即時(over-the-shoulder)代碼審查:當前代碼必須被review後才能往下進行,呈阻塞式;
- 工具支持的(tool-assisted)代碼審查:將代碼提交後,開發者能夠繼續往下編碼,reviewer有空後進行review
- 圓桌CR(round-CR):就核心代碼,組織會議進行CR
若是由於CR流程重浪費時間,最後只停留在結對編程這種階段最後會形成浮於表面,必將失去效果。結對編程通常是指,開發者知道當前被一個問題卡住了,去和其餘人進行溝通,這裏,會有一個很強的假設條件,就是開發者知道當前編碼存在問題或者進行不下去了,纔會發起這種CR。事實上,這種很強的假設條件就是一個危害因子,一旦有假設就一定埋下隱患。就相似於編碼中一旦假設系統非空的強約束,而後線上一旦出現空的狀況,瞬間崩潰。事實上,大多數狀況下,人會陷入到」我本覺得是對的,其實是錯的「的境地。若是開發者都能知道問題所在進行解決,那爲何會有那麼多線上故障以及風險呢?依賴人性本就是一個危險的舉動,僅僅依賴於結對編程的形式的CR本就是一個僞命題。
針對這四種不一樣形式的CR的適用場景概括總結以下:
結對編程(pair programming)
當你須要解決一個複雜問題時,這種代碼審查的方法很適用。在仔細尋找解決方案的過程當中,把兩我的的腦力彙集起來,會增長成功的概率。讓兩個頭腦思考同一個問題,並相互討論可行的方案,這樣你會更可能覆蓋到問題的一些邊界狀況。結對編程適用於兩個有類似經驗水平的開發者處理複雜的業務問題的狀況。
即時(over-the-shoulder)代碼審查
若是代碼編寫者缺少經驗,寫出的代碼須要很大的改進,那麼同步代碼審查也會頗有效。若是一個經驗豐富的高級開發者將要對一個很初級的程序員寫出的一段代碼進行審查,那麼,當初級程序員寫完代碼後就和高級開發者一塊兒改進這段代碼,效率是遠遠高於初級程序員本身一我的看的。但也存在,須要打擾別人的狀況,影響工做效率,而對開發者而言,若是不review經過,沒法進行下去,是阻塞式。
工具支持的(tool-assisted)代碼審查
工具支持的(tool-assisted)代碼審查,總體流程是異步進行的,開發者提交代碼,而後等待reiewer去查看。開發者不須要直接依賴於審查者,而且他們均可以按本身的時間表去作各自的工做。但也存在一個缺點是,review以後,開發者又須要切換回以前的思路去回想以前是怎麼想的。
圓桌CR(round-CR)
在針對核心流程以及系統基礎結構的代碼時,每每須要以一種正式的形式去review,以儘早的規避風險。
不一樣的CR形式的適用場景須要根據當前的代碼所要解決的問題屬性進行選擇,沒有固定的方式,只有合適的方式,好比」直譯式業務代碼「就能夠採用結對編程的方式進行解決,研發過程當中足夠敏捷的話,能夠在選擇部分業務節點進行」異步CR「的形式,在」核心業務代碼以及基礎架構「的代碼上就能夠引入圓桌CR。
何時須要引入CR,這裏,從兩個維度來看:
對團隊而言
CR對於團隊來講,必然會佔用一部分研發時間,什麼樣的團隊須要引入,在Who—什麼樣的團隊須要引入CR 中進行的介紹。總結起來就是,願意培養工程師文化以及培養團隊的技術信仰,並願意爲此花費的時間買單。另外,若是業務迅猛發展,支持業務的發展優先級更高,不引入CR也是正確的,只有最合適,沒有最正確。
在研發流程的不一樣節點上來看
在第4部分Where中概括了四種常見的CR方式,這四種CR方式的存在也是爲了解決不一樣問題場景而存在的,要根據不一樣的場景選擇合適的方式。至少在技術方案肯定,業務流程梳理出來的那一刻起,就應該清楚哪些代碼實現是須要Round-CR,由於若是連當前系統迭代的核心都不清楚的話,那麼這個技術方案也必然是失敗的。
關於如何進行CR,在what、Why、Who和Where幾個部分都分別論述了CR的幾個關鍵要素,下面關於CR落地執行給出個人思考。
團隊心智達成一致
CR是一項團隊協做的過程,要想可以達到高效率高收益,出發點必然會是團隊成員在乎識層面上達成一致,這裏須要一種契約精神,在CR中每一個人承擔的角色如speaker、reviewer-ownner、reviewer-expert以及recorder在」Who「的部分都給出了相應的責任範圍,包含了什麼是應該作的,什麼是不該該作的論述。每一個角色,都應該按各自的角色達成一致,努力並主動的承擔這部分職責。
合理的選擇CR
是否是每一個項目就必定須要CR了(或者僅僅採用結對編程的方式),也須要根據事情狀況,若是業務發展迅速,或者存在頻繁的業務變動,有可能這期項目廢了很大的力氣去作CR,保證了代碼質量,後期業務發生變化,會讓這一期的努力付之東流。業務型系統,永遠將業務放在第一位,若是業務發展快,開發週期短,CR太重必然會形成技術的疲於奔命,團隊引擎燃油不足後勁不足的狀況。也就是說,CR須要根據當前項目的屬性,以及對當前業務的走向趨勢進行預測,選擇合適的CR的形式,如結對編程或者round-CR。又想要A又想要B,每每是一種引火自焚的方式。
肯定checklist
在CR前,須要根據團隊的現狀,制定CR的checklist,也就是在CR中必需要檢查的項目,如代碼的規範性等多個方面。常見的有以下:
另外在這篇文章中,給出了常見的checklist的項目: checklist.png
控制CR的粒度
對代碼來講,CR應該是以一個接口(service)開始,對當前接口進行CR,可想而知,若是一個鏈路過長,代碼量過多的話,基本會讓人心煩意亂,更談不上給出合理的建議了。也就是說CR的頻率,以及對代碼的粒度要進行控制,而這部分也應該是在團隊進行規定;
心態上的準備
CR是一個協同和溝通的過程,對新人來講渴望通過CR可以學習到前輩們的經驗以及從前輩們那裏獲得切實的指導,不管是哪個角色上,在心態上都應該保證平等尊重,簡單且信任的態度,不要抱有挑剔的眼光以及炫技的心態。
總體CR流程以下:
從上圖能夠看出主要分爲三個部分:
業務review
待開發者提交代碼後,須要按照團隊制定的checklist進行業務評審,這部分主要是check有沒有處理一些異常case,在業務執行流程中有疏漏的點,也就是說這部分除了團隊制定的checklist是一定檢查項外(checklist每每是從技術層面來約束),根據當前的業務流程也須要check,這部分背景色是紅色,也就是說這是業務的高壓線,業務review不經過直接打回,待經過後才能往下繼續;
溝通學習
起初準備叫技術review,後來一想,這裏的代碼已經經過了業務,也就是說知足了上線的基本要素,若是不進行CR,可能這些代碼就已經上線了,可是這裏,會被拿出來繼續討論,就代碼的設計模式、算法複雜度、代碼是否可以更加簡化等各個層面進行討論,也就是我想推進CR的一個緣由,這部分是新人向老司機學習的最好機會,不用再苦於沒有真實案例,只學到皮毛,擺在眼前就是真實的場景,新人天然不能放過。這部分背景色是綠色,正如我初衷,是開放高效的,也是CR的附加值;固然這裏,須要給出具體的建議如僞代碼或具體知識點,若是隻是侃侃而談,沒有多大的用處。這部分討論的再也不是業務,也就是說再也不是PD的非功能性需求,也是開發者探索的寶地;
修復問題
在溝通學習階段,會產生問題,這類問題能夠分爲兩種形式:1. 簡易修改型代碼;2. 需重構代碼或重大調整。
針對第一種簡易修改型代碼如fori
的語句採用lambda去寫,將功能性代碼抽取出來不要污染業務方法等狀況,能夠立馬去執行修改,優化代碼質量。
還有一種是重大重構如引入策略模式去除if-else,加入緩存等涉及到優化修改,我認爲是能夠延緩的,程序員是一個長時間加班的職業,在CR中若是涉及到這類修改無疑佔用大量時間,擠壓了開發時間,而後頻繁加班,會讓開發者疲於奔命,整個團隊士氣低落。另外,在業務初期,軟件系統的使用時保證業務快速落地,也就是說在業務快速發展時期,對代碼也應該具有容忍度,讓業務快速落地拿到的結果更爲豐盛。這個時候就能夠申請滯後處理,也就相應的設計到重構的知識,也能夠做爲團隊分享。
而這部分時間投入理論上會隨着重構次數增長,經驗積累愈來愈豐富,出現的問題愈來愈少,這部分申請的修復人日也愈來愈少。
CR主要流程經過三個方面完成對代碼質量的提高和問題的收口,關係以下圖:
能夠看出好的CR必定是分階段去review,也就是說當聚焦到業務review時就不要去向speaker提出技術上的意見,能夠先記錄下來,待下一階段在提出,一塊兒商討處理,每一個階段聚焦到其對應的聚焦點上,不然就出現你在說A,我在說B,起爭執也達不到好的效果。
CR是被認爲一種工程師文化的表明,在IT圈也一直盛傳着各類文化,如極客文化,hackthon等等,在這裏我也認爲CR應該被視之爲一種文化,而非一種極其機械的手段。何爲文化,就應該是人心裏心之嚮往,並外在委以寄託。古有李白杜甫騷客以唐詩宋詞寄託,今有,朝聖者三拜九叩走向布達拉宮,咱們總會有那麼一種心裏驅使的東西須要去安放。但是,咱們早就習慣由於」數字「而自嗨。
迪士尼樂園來到上海時,網上就有消息聲稱萬達樂園在江浙滬三地進行攪局,而國人也一度習慣由於數字去評判事情的利弊好壞。在網上隨便google下,能夠發現香港迪士尼,巴黎迪士尼等多地都處於常年虧損的地步,你會認爲迪士尼是失敗的嗎?當小朋友們沉浸在獅子王,沉浸在米奇的世界裏,咱們不該該感謝迪士尼爲小朋友們帶來了這麼一個精彩純真的世界嗎,那麼,憑着業績數字可以認爲迪士尼是失敗的嘛?就像今天你評判好萊塢文化,你永遠不會由於賣了多少票房去量化的去評判,只會記得那些蜘蛛俠、蝙蝠俠一個個角色告訴每一個人作好本身,都是蓋世英雄。也許有人會說,文化和市場化是兩個不一樣的東西,二者相互促進。誠然沒錯,但我相信市場化是文化催生的另外一種形態而已。可是,在今天的大環境,咱們已經麻木的喜歡由於」數字「而自嗨,而由於社會這樣的」通病「,咱們看到的所謂工程師文化,極客文化,都好像有點失去了味道。
**CR一樣應該被當作一種文化去培養,更像是一種軟性的力量,去開發者聯繫在一塊兒的感情繫帶。**若是在一開始,就想着去量化,開始是否是就是一個錯誤的開始呢?人性上一直存在的陰暗面,看到數字就會想着美化,管理者看到數字就被視爲一種政績,聚焦點就在這個冷冰冰的數字上,這種文化,如何落在開發者的信念上,若是一旦不能,CR就已經在走向成爲負擔的路上。
因此,我認爲CR的推行,必定是思想上」輕「,輕量化,不要由於數字而自嗨,可是,流程上」重「,這個重體如今對CR這項協同活動上各個角色完成相應的契約精神。
若是非要以一個量化去評判CR落地的效果,我也認爲不該該從CR中提煉出的各類數據,去看看項目交付後用戶反饋有沒有更好,去看看團隊的精氣神是否是有沒有更好,去看看CR能側向影響的層面,這些我認爲是CR帶來的最大的改變,就像文章開始所說,問題,永遠只是CR的副產品!
退一萬步說,從沒有CR,到引入CR直至落地,拿到的不就是一種結果嗎?只要開始就本是一種結果。
若是說最爲理想的狀態,CR會是彼此成長,簡單高效,知識傳播的一種踐行的最佳途徑。(開發者互相尊重,相親相愛,因而,以下圖 博君一笑.png)