1. what—什麼是CR
codereview(CR)一直以來在軟體行業被視為提升程式碼質量的一種有效的方式,也被視為一種工程師文化的代表。關於什麼是CR,在goole出具體的定義如下:
程式碼評審是指在軟體開發過程中,對原始碼的系統性。通常的目的是查詢系統缺陷,保證軟體總體質量和提高開發者自身水平。 Code Review是輕量級程式碼評審,相對於正式程式碼評審,輕量級程式碼評審所需要的各種成本要明顯低的多,如果流程正確,它可以起到更加積極的效果。正因如此,輕量級程式碼評審經常性得被引入到軟體開發過程中。
從上面的解釋中可以基本上可以看出CR的幾個核心關鍵點:
- CR應該是處在研發流程中,並不是專案結束之後,也就是說CR應該是存在於研發流程之中的事情,只有在過程中進行才能確保最終的交付結果,而不是最後的亡羊補牢和自怨自艾;
- CR的目的是提前發現系統缺陷,進而提前解決,事實上,CR的目的不僅僅是發現問題,而是開發者在一起進行溝通和協同的過程,主要的目的還是為系統質量負責的一種手段,但收益卻會遠遠超過此點;
- CR是輕量級程式碼的check和溝通,所以說要想完成一次質量很好的CR,前提條件是足夠輕量,這個輕量體現在兩個方面:一是程式碼review量,可想而知,如果一次程式碼量很多,甚至超過幾百行,人會產生疲倦感,自然而然review的質量會下降,最後成為了走馬觀花的形式,也就是說大多數情況下要實現CR需要以小步快跑的方式實現;二是程式碼結構足夠輕量,這個輕量主要是程式碼結構清晰,最起碼的遵守類唯一職責原則以及每個方法的程式碼行數不宜過多等基本開發約束,只有這些前提滿足的情況下,程式碼結構清晰,更能讓reviewers能夠理解你想表達的意思,並且,結構清晰會提升程式碼的美感,自然而然會提升reviewers的參與感和幸福感;
- 最後有這麼一句話是”如果流程正確,它可以起到更加積極的效果“,正如萬事萬物,一半天使一半魔鬼,只有根據團隊的情況選擇合適的CR方式,才能收穫到效果獲得收益,否則就會成為負擔,成為團隊偏離正常軌道的導火線。
可以發現,CR在研發流程中如果合適的引入進來,無疑會大大增強系統的程式碼質量,促進團隊的的發展。但同時,也需要一起根據團隊的現實,去因地制宜確定方案。
2. Why—為什麼要引入CR
關於為什麼要引入CR,我也一直在想這個問題,推行CR的最大的阻力無外乎在於流程的執行需要時間落地,而這部分流程也一定會很重,一定需要團隊在時間上願意為引入這個流程進行買單。除此之外,不合適的CR方式也一定會造成很多負面的影響:
- 在CR流程上不對的情況下,一定會出現下面的場景:
A:這段程式碼需要在這裡,這裡,還有那裡進行改動;
B:LZ程式碼明明質量很好了,you can you up, no can no bb
A:這段程式碼你一定要改;
B:心裡很複雜,思想上很累
如果CR執行的流程不對,一定會出現這種情況,如果一旦出現這種情況,CR的推行必然就是會失敗的,嚴重的話會損傷小夥伴感情,同時會影響團隊的開發氛圍,但我覺得,出現這種情況,有個根本的原因在於CR流程上在每個階段上聚集的點不一樣造成的,通俗的來說,就是你在說A,TA在說B,如何解決這樣的問題,我的思考會在下面給出。
- 過分佔用開發時間,對於開發者來說,最需要的是安安靜靜能夠開發的時間,如果在CR的過程中沒有聚焦點,在個別點的討論上沒有收住的話,對CR來說也是失敗的,因為大量的擠佔了開發時間,帶來的就是開發者又需要熬夜加班,久而久之,就是在心裡上建立心裡防線和壁壘;
當然關於,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最終的作用將歸到促進工程師日常程式碼交流和人員的成長上面來,與此同時作為輔助手段來對產品質量進行把關。
3. Who—參與CR的主體
CR是一項協同活動,在推行CR之前,也需要明確參與到CR的主體。CR這項活跟團隊狀態、團隊技術信仰以及團隊訴求有關,由於與”人“掛鉤也必不可少跟”人“這個因素有關,當然必不可少的還有程式碼和參與這項活動的各個人員。
3.1 什麼樣的團隊需要CR
團隊花精力引入CR自然而然是期待這種輔助手段以解決某些問題,也就是說當前團隊希望藉助CR以實現進階突破,那麼下面幾種團隊型別有必要引入CR:
- **技術驅動型團隊:**一般涉及系統底層邏輯較多,功能路徑難以被測試覆蓋,而產品質量問題很多時候是致命的,所以這樣的團隊更多需要開發編碼的嚴謹性和相關程式碼質量的保證活動;
- **公共服務型團隊:**一般服務於多個團隊,一旦出現質量問題影響範圍會比較廣,所以除了在測試方面加以把關外,通過CodeReview活動來提升開發質量是非常有必要的;
- **測試缺失型團隊:**團隊由於缺乏正式專業測試環節,開發自測容易陷入自己的開發邏輯中,以及由於開發者往往只對當前業務模組熟悉,只能覆蓋到當前業務模組的測試,針對A和B業務結對可能造成質量問題可能無法覆蓋到自測中,質量問題帶到線上的風險會很高,強烈建議在CR環節進行溝通碰撞以降低這種風險;
- **新人密集型團隊:**新人的程式碼可讀性往往是比較差的,特別需要組織能及時給予糾正,幫助新人養成良好的編碼習慣。同時如果團隊產出的程式碼可讀性較高時,新人也可以更快上手工作;
- **任何有主觀意願的團隊:**這樣的團隊或領導者認同CodeReview的意義,或團隊成員對程式碼質量提升有追求。
那麼什麼樣的團隊不需要引入CR呢?
- **不認同型團隊:**即領導和團隊骨幹都不認同CodeReview意義的團隊,這樣的團隊無論從推動還是堅持上都有很大挑戰。
- **疲於應付型團隊:**這種團隊一般沒有建立必要的持續提升機制,每天淹沒在各種需求溝通實現變更和優化中,自然,程式碼質量提升活動也很難被列入backlog。
- **創新型團隊:**這種團隊的重要任務是要把產品快速推向市場進行價值驗證,所以在程式碼編寫上要求足夠敏捷,程式碼暫時的混亂完全可以接受。
3.2 什麼樣的程式碼需要引入CR
CR的另一個主體肯定是程式碼,也是開發者討論的主體物件,是不是所有的程式碼都需要引入CR,我的觀點是不必的。
3.2.1 哪些程式碼需要引入CR
核心鏈路業務程式碼
在複雜的業務場景下,承擔主要的業務功能的程式碼需要拿出來CR,那麼如何來衡量哪個部分是核心鏈路呢?從業務流量分佈上來看,在網際網路應用中有28原則,即80%流量在20%的資料(業務)中,那麼這20%的業務程式碼就是需要拿出來CR的,這部分程式碼承擔了本次迭代核心功能,也是使用者最為care的點,同時也是本次軟體業務週期中聚焦點,也是PD的強功能性需求,自然而然也是需要被格外重視的地方,如果存線上上風險,損失是巨大的。
系統底層框架核心程式碼
從系統的基礎建設角度來看,PD的需求一般是功能性需求,無暇顧及到系統的非功能性需求,這部分是開發者賦予系統的健壯性,而這部分關乎到軟體系統是否能夠提供強健的生命力,也被視為系統的引擎。舉例來說,在協同平臺專案管理三期專案—里程碑規範中,通過里程碑模板建立里程碑以及里程碑時序規則校驗機制,就被視為這期專案的”基礎建設“,理所當然也應該被拿出來CR,如果存在問題,必將”風雨襲來,大廈將傾“!
事實上,以上兩種型別的程式碼在技術方案評審就可以被確定下來,並需要進行round CR進行。
3.2.2 哪些程式碼是不需要引入CR
業務直譯式程式碼
參照流量分佈,總有一部分業務功能並非使用者關心的核心功能,只是因為系統功能完整性而存在,或者業務流程很簡單,從controller-->service-->dao參照PRD”翻譯式“編寫的程式碼(稱之為業務直譯式程式碼),客觀來說並不需要花費長時間進行round CR。但是不是就一定不需要CR呢?也是未必的,只是流程就不需要那麼重,可以採用deskmate CR(即同桌間進行溝通),也就是peer programmer(結對程式設計),兩人進行簡單高效的溝通即可。
3.3 什麼樣的人需要參與到CR
CR終究是一件與人相關的活動,並且CR的質量也跟人之間溝通協作效率掛鉤。因此,要想獲得高質量的CR,就需要理清CR中參與的人員角色,並賦予相應的職責。
主講人(speaker)
speaker即為當前走讀程式碼的開發者,我更願意將其稱之為speaker,而不是被review的人。speaker是出現在學術會議以及各種技術會議上,宣講自己的思想和概念的人。我也認為,每一個走讀程式碼的人,應該抱有這份自信,去向其他開發者合理清晰且邏輯清晰的表達自己的觀點,如果自己都不能很自信,如何去說服其他人呢,程式碼應該是開發者的藝術品。所以,對speaker來說有以下職責:
- 應該做的
- CR前在腦子裡應該有清晰的脈絡,最好是心裡能夠默默的說一次,這是speaker的職責,也直接關係到CR的效率和最終的效果;
- 增強程式碼的可閱讀性,學會換位思考,程式碼結構一團糟,對reviewers來說CR是絕對不能通過的,要讓別人怎麼能夠看到一團糟的東西有興趣起來呢?
- 更加自信一點,這是每一個開發者溝通表達的機會,總有人會吐槽程式設計師很悶,不善言辭,抓住這些小的機會,你一定會是一個閃光的人。
- 不應該做的
- CR前毫無準備,疲於應付,這無疑是浪費大家的時間,如果遇到這種情況,reviewers可以合理的給出建議,督促其意識到問題所在,CR說到底是一件協同的事情,那麼一定要有人遵守這項基本的遊戲規則。
- 不要聽不進去別人的建議,欣然接受其他人給出的合理建議,因為這本就是一個很好的學習機會。
reviewers
reviewers是指對開發者程式碼提出建議的人,在這裡角色中也可被拆分成兩類角色:
-
reviewer-ownner
這個角色被認為是對當前系統最為熟悉的人,可以說是當前系統的建立人,熟悉系統的各處神經脈絡。因此在reviewer時,需要觀察當前開發者的程式碼是否會傷害已有的架構。除此之外,這種角色也應該具備業務的感知能力,除了完成當前需求外,憑藉其自身的業務感知能力,應該對當前系統功能走向有所預測,需要判斷當前開發者的程式碼能夠對未來的業務有擴充套件性和支撐性。這類角色,遵守的基本原則是”大處著眼“。
-
reviewer-expert
事實上,在reviewer-ownner這類角色中基本上已經不是一線開發者,在CR中肯定需要經驗豐富的開發者,而這個角色基本上在CR過程中,憑藉其自身的經驗會對開發者程式碼就具體的點提供細緻的建議,而這些建議就是推動團隊程式碼規範以及質量的關鍵要素,這類角色,遵守的基本原則是”小處著手“。
那麼針對這類角色應盡的職責有哪些呢?
- 應該做的
- 以對系統負責的態度,切實對speaker的程式碼進行合理的評價和給出建議;
- 不要刻意的去發現問題,當然CR的主要目的是找出問題,但是在這個過程中,需要保證心態上的平衡,刻意的做一件事情就會顧此失彼,失去更重要的東西,我堅信,問題,永遠只是CR的副產品。
- 不要按照自己的風格去觀察別人的程式碼,程式碼是每個開發者的藝術品,在寫程式碼時每個人會有自己的編碼風格以及設計思路,如果你一開始就帶著有色眼鏡去看的話,任何地方都會覺得不順眼,而忽略重要的東西,而失去了CR的聚焦點。對revierers而言,這也是瞭解其他思路的一種方式。
- 不要質疑別人的能力以及打擊的心態,這種心態在CR過程中是一種大忌,參與CR中的每個人都應該簡單、信任並相互尊重。如果有這種心態,就會產生不必要的爭論,甚至會讓CR成為一種心理上的負擔;
- 不要在不確定的問題上爭論太久,在一些具體的細枝末節上,爭論太久會阻塞整體流程,並會造成負面消極的影響,這個時候需要有人中斷,暫且擱置爭議;
- 不應該做的
- 只發表言論,不給出具體方案或可切實執行的意見。我們都討厭誇誇其談的演說家,對每一個參與者來說,都希望在CR過程中學到其他人可以落地有效的解決方案和建議,在CR的過程中,面對的是具體問題,對reviewers來說完全可以就具體問題和開發者一起分析,並結合reviewers已有的技術案例給出具體的方案,這是一個傳承的機會。如果只發表言論的話,畢竟從一個請求到最後完成請求的處理,經過了那麼多步驟,可以演說的太多,但帶來的東西基本為零;
recorder
在CR的過程中,理所當然需要記錄後續的action,也就是說需要這麼一個角色負責這個事情。單獨需要這麼一個角色在於speaker和reviewer在CR過程中需要進行溝通表達,如果停下來來記錄,分散其注意力,整個過程往往就不會一氣呵成,會大大損失CR的快感。那麼對這類角色有如下職責:
- 應該做的
- 抓住speaker和reviewer的分歧點,這是CR的產物,也是推動系統進化的突破點,recorder需要對其進行詳細記錄,作為後續的action。
- 不應該做的
- 認為在CR中承擔職責不重要,對recorder而言,**千萬不要認為,自己僅僅就是一個記錄的人員,就畫地為牢,**因為一旦有這樣的心態的話,必然會造成在CR過程中精神不集中,漏掉很多有意義的點,實際上,對recorder來說,你也是一名reviewer,只是你需要多承擔一部分recorder的職責而已。
以上四個角色會存在在CR過程中,但四個角色並不一定就是多個人,每一個只負責一個角色。也有可能是一個人,負責多個角色,比如結對程式設計中往往只有兩個角色,那麼這個speaker又要負責程式碼的走讀以及作為recorder進行記錄。對角色責任範圍一定要理清,不然在CR過程中就是無頭蒼蠅,找不到發力點。
4. Where—不同的研發節點進行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。
5. when--什麼時候引入CR
什麼時候需要引入CR,這裡,從兩個維度來看:
-
對團隊而言
CR對於團隊來說,必然會佔用一部分研發時間,什麼樣的團隊需要引入,在Who—什麼樣的團隊需要引入CR 中進行的介紹。總結起來就是,願意培養工程師文化以及培養團隊的技術信仰,並願意為此花費的時間買單。另外,如果業務迅猛發展,支援業務的發展優先順序更高,不引入CR也是正確的,只有最合適,沒有最正確。
-
在研發流程的不同節點上來看
在第4部分Where中歸納了四種常見的CR方式,這四種CR方式的存在也是為了解決不同問題場景而存在的,要根據不同的場景選擇合適的方式。至少在技術方案確定,業務流程梳理出來的那一刻起,就應該清楚哪些程式碼實現是需要Round-CR,因為如果連當前系統迭代的核心都不清楚的話,那麼這個技術方案也必然是失敗的。
6. How--如何進行CR
關於如何進行CR,在what、Why、Who和Where幾個部分都分別論述了CR的幾個關鍵要素,下面關於CR落地執行給出我的思考。
6.1 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中必須要檢查的專案,如程式碼的規範性等多個方面。常見的有如下:
- 《java開發規約》
- 團隊開發規約
- 《effective-java》(可檢視本人部落格)
- 《程式碼大全》
- 《clean code》
另外在這篇文章中,給出了常見的checklist的專案: checklist.png
-
控制CR的粒度
對程式碼來說,CR應該是以一個介面(service)開始,對當前介面進行CR,可想而知,如果一個鏈路過長,程式碼量過多的話,基本會讓人心煩意亂,更談不上給出合理的建議了。也就是說CR的頻率,以及對程式碼的粒度要進行控制,而這部分也應該是在團隊進行規定;
-
心態上的準備
CR是一個協同和溝通的過程,對新人來說渴望經過CR能夠學習到前輩們的經驗以及從前輩們那裡得到切實的指導,無論是哪一個角色上,在心態上都應該保證平等尊重,簡單且信任的態度,不要抱有挑剔的眼光以及炫技的心態。
6.2 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,起爭執也達不到好的效果。
6.3 如何衡量CR的效果
CR是被認為一種工程師文化的代表,在IT圈也一直盛傳著各種文化,如極客文化,hackthon等等,在這裡我也認為CR應該被視之為一種文化,而非一種極其機械的手段。何為文化,就應該是人內心心之嚮往,並外在委以寄託。古有李白杜甫騷客以唐詩宋詞寄託,今有,朝聖者三拜九叩走向布達拉宮,我們總會有那麼一種內心驅使的東西需要去安放。可是,我們早就習慣因為”數字“而自嗨。
迪士尼樂園來到上海時,網上就有訊息聲稱萬達樂園在江浙滬三地進行攪局,而國人也一度習慣因為數字去評判事情的利弊好壞。在網上隨便google下,可以發現香港迪士尼,巴黎迪士尼等多地都處於常年虧損的地步,你會認為迪士尼是失敗的嗎?當小朋友們沉浸在獅子王,沉浸在米奇的世界裡,我們不應該感謝迪士尼為小朋友們帶來了這麼一個精彩純真的世界嗎,那麼,憑著業績數字能夠認為迪士尼是失敗的嘛?就像今天你評判好萊塢文化,你永遠不會因為賣了多少票房去量化的去評判,只會記得那些蜘蛛俠、蝙蝠俠一個個角色告訴每個人做好自己,都是蓋世英雄。也許有人會說,文化和市場化是兩個不同的東西,兩者相互促進。誠然沒錯,但我相信市場化是文化催生的另一種形態而已。但是,在今天的大環境,我們已經麻木的喜歡因為”數字“而自嗨,而因為社會這樣的”通病“,我們看到的所謂工程師文化,極客文化,都好像有點失去了味道。
**CR同樣應該被當做一種文化去培養,更像是一種軟性的力量,去開發者聯絡在一起的感情繫帶。**如果在一開始,就想著去量化,開始是不是就是一個錯誤的開始呢?人性上一直存在的陰暗面,看到數字就會想著美化,管理者看到數字就被視為一種政績,聚焦點就在這個冷冰冰的數字上,這種文化,如何落在開發者的信念上,如果一旦不能,CR就已經在走向成為負擔的路上。
所以,我認為CR的推行,一定是思想上”輕“,輕量化,不要因為數字而自嗨,但是,流程上”重“,這個重體現在對CR這項協同活動上各個角色完成相應的契約精神。
如果非要以一個量化去評判CR落地的效果,我也認為不應該從CR中提煉出的各種資料,去看看專案交付後使用者反饋有沒有更好,去看看團隊的精氣神是不是有沒有更好,去看看CR能側向影響的層面,這些我認為是CR帶來的最大的改變,就像文章開始所說,問題,永遠只是CR的副產品!
退一萬步說,從沒有CR,到引入CR直至落地,拿到的不就是一種結果嗎?只要開始就本是一種結果。
如果說最為理想的狀態,CR會是彼此成長,簡單高效,知識傳播的一種踐行的最佳途徑。(開發者互相尊重,相親相愛,於是,如下圖 博君一笑.png)