【分享】 codeReview 的重要性
為什么要做代碼 Review
為什么要代碼 Review,相信每個人心中都有比較一致的答案,Google 搜索一下也能找到一大堆的文章。這里簡單總結(jié)幾點:
1)提高代碼質(zhì)量
這是代碼 Review 的初衷,也是代碼 Review 最直接的價值。Reviewers 根據(jù)各自的經(jīng)驗,思考方式,看問題的角度給代碼提出各種可能的改進意見,從而形成更好的代碼以及產(chǎn)品質(zhì)量。
我們知道產(chǎn)品問題越晚提出解決它的代價就越大,參與進去的人、要走的流程都會越來越多。代碼 Review 可以說是早期解決問題最有效的途徑之一了,在代碼 Review 中解決掉哪怕一個小問題都能避免后續(xù)一堆的麻煩事。
2)形成團隊統(tǒng)一的高質(zhì)量標(biāo)準(zhǔn)
有效的代碼 Review 最終會在團隊范圍內(nèi)建立起統(tǒng)一的質(zhì)量標(biāo)準(zhǔn),并且會隨著團隊成員的互相學(xué)習(xí)和促進形成更高的標(biāo)準(zhǔn)。參與者會在代碼 Review 的過程中基于具體問題從不同角度提出改進意見,并最終做出當(dāng)前最佳的選擇并形成共識。隨著代碼 Review 的有效進行,團隊成員會有意識地關(guān)注代碼質(zhì)量,從而形成越來越高的事實上的質(zhì)量標(biāo)準(zhǔn)。
3)個人快速成長
通過有效的代碼 Review,Author 和 Reviewer 都將獲得成長,在 Review 過程中參與人就具體的問題展開深入的討論,無論是怎么寫出整潔的代碼、怎么更好地更全面地思考問題、怎么最佳地解決問題,參與人都可以互相取長補短,互相提高。通過具體代碼實現(xiàn)進行的討論往往是最深入和有效的,代碼 Review 是開發(fā)者提高代碼能力最重要的途徑之一。
有的人認(rèn)為代碼 Review 就是 Reviewer 幫助查找代碼中的 Bug,其實代碼 Review 不應(yīng)該是一個單向的過程,而應(yīng)該是個雙向交流的過程,Reviewer 幫助 Author 提出代碼改進意見的同時,也是向優(yōu)秀的 Author 學(xué)習(xí)的過程。我們都知道提高代碼能力一個有效的途徑是閱讀優(yōu)秀的項目代碼,但是閱讀項目代碼有著不小的難度,這也是大部分人沒有去執(zhí)行的原因,而 Review 資深同事的代碼,我們在閱讀代碼的同時能夠直接進行有效的溝通,這是一個快速有效的學(xué)習(xí)途徑,尤其對開發(fā)經(jīng)驗還不算豐富的開發(fā)者而言。
如何做好代碼 Review
2.1. 什么時候發(fā)起 Review
在代碼 Review 上,Author 需要意識到:Reviewer 的時間是昂貴的。因此在正式邀請 Reviewer 發(fā)起代碼 Review 前,Author 有幾項需要注意的點,這些都能提高代碼 Review 的效率,節(jié)省 Reviewer 的時間。
2.1.1. MR (Merge Request)
也稱為 PR(Pull Request), MR 是我們進行代碼 Review 的地方,它記錄著代碼的具體改動,參與者具體的討論過程。好的 MR 應(yīng)該做到以下幾點:
-
單一:
一個 MR 應(yīng)該只解決一個單一的問題,無論是修復(fù)一個 bug,還是實現(xiàn)一個新 feature。
Author 應(yīng)該避免一個 MR 包含不同意圖的代碼改動。
單一的 MR 能幫助 Reviewer 快速地了解代碼改動的動機,能有針對性地進行 Review。
?
-
短小:
MR 應(yīng)該盡量地小,比如一個 feature 引入了較多的改動,需要考慮是否可以拆成獨立的幾塊實現(xiàn),分開提 MR,比如接口定義、接口實現(xiàn)、邏輯對接等拆分開。
?
-
詳細(xì): 這里說的詳細(xì)是指 MR 應(yīng)該盡可能地詳細(xì)描述它的背景和動機,可以是在 MR 的描述中詳細(xì)體現(xiàn),也可以是連接到具體 issue 或 tapd 單中。
需要達到的目的是,其他人翻開一個 MR 能知道當(dāng)時做這個改動的背景以及動機。
?
2.1.2. Commit Message
之前翻看了不少現(xiàn)存的項目代碼,看到不少的 Commit Message 寫得比較簡單,例如一連串的 "update", "fix",從這些 Commit Message 中完全看不出做了什么改動,想想如果之后想要定位之前的某個改動,該從哪里下手。
目前 Commit Message 規(guī)范比較常見的有?Angular 團隊的規(guī)范,并由此衍生出了?Conventional Commits Specification,可以參照此 Specification 約定 Commit Message 格式規(guī)范。
<type>(<scope>): <subject><BLANK LINE><body><BLANK LINE><footer>大體分三行:
-
【標(biāo)題行】?必填, 描述主要修改類型和內(nèi)容。
-
【主題內(nèi)容】?描述為什么修改, 做了什么樣的修改, 以及這么做的思路等等。
-
【頁腳注釋】?放 Breaking Changes 或 Closed Issues
其中 type 是 Commit 的類型,可以有以下取值:
-
feat:
新特性
-
fix:
修改 bug
-
refactor:
代碼重構(gòu)
-
docs:
文檔更新
-
style:
代碼格式修改
-
test:
測試用例修改
-
chore:
其他修改, 比如構(gòu)建流程, 依賴管理
其中 scope 表示的是 Commit 影響的范圍,比如 ui,utils,build 等,是一個可選內(nèi)容。
其中 subject 是 Commit 的概述,body 是 Commit 的具體內(nèi)容。
例如:
fix: correct minor typos in codesee the issue for details on typos fixed.Refs #133Commit Message 可以在 git 中配置模板,這樣可以在 vim 中展示出模板,另外可有工具幫助我們生成和約束 Commit Message,例如 commitizen/cz-cli,這里不再具體說明。
2.1.3. CI 通過
CI(Continuous Integration),持續(xù)集成可以幫助我們自動發(fā)現(xiàn)很多代碼中的基本問題,在合適的靜態(tài)代碼檢查(lint)配置和良好的單元測試覆蓋下,CI 可以有效地提高代碼的質(zhì)量。很多人都低估了靜態(tài)代碼檢查的能力,實際上現(xiàn)在常見語言的靜態(tài)代碼檢查已經(jīng)能幫助發(fā)現(xiàn)不少的 bug 和隱患。對于 Go 語言,可以配置 golangci-lint 來做代碼檢查,單元測試根據(jù)實際情況可以制定相應(yīng)的標(biāo)準(zhǔn),比如覆蓋率 60%,其中關(guān)鍵的代碼邏輯盡量全面覆蓋。
提交代碼 Review 前需要確保 CI 執(zhí)行通過,這也是為了節(jié)省 Reviewer 的時間,能夠通過自動化解決的事情,盡量不要讓 Reviewer 來做,而 Reviewer 發(fā)現(xiàn) CI 未過的 MR 也可以要求 Author 先解決 CI 問題。
2.1.4. Self-Review
我們一般代碼 Review 都是找他人來進行 Review,其實負(fù)責(zé)任的 Author 在邀請他人來代碼 Review 前也需要自己簡單 Review 一遍,即 Self-Review。
Self-Review 的目的包括:
-
發(fā)現(xiàn)那些明顯的疏忽,如代碼 debug 過程中留下的不必要的痕跡,比如 fmt.Println(...),不小心注釋掉的代碼。
-
之前被 Reviewer 多次提出過的問題。
-
Commits 是否正常,在多人協(xié)作的情況下 MR 中否帶入了不相關(guān)的 Commit。
-
Commit Message 是否合適。
Self-Review 是一個非常快速的過程,從我個人的經(jīng)驗,一般 1-2 分鐘即可完成,所以推薦大家養(yǎng)成 Self-Review 的習(xí)慣。
2.2. 該找誰來 Review
從目的出發(fā),可以從以下幾方面考慮 Reviewer:
-
提高代碼質(zhì)量。
所以首先應(yīng)該找和代碼改動緊密相關(guān)的研發(fā)人員參與 Review,比如一起開發(fā)某個功能,某個項目,或者一起參與了方案設(shè)計討論并給出了有價值意見的研發(fā)。
-
獲取意見。
找有相關(guān)經(jīng)驗的資深研發(fā)幫忙 Review,比如 Java 語言資深的研發(fā)、寫過相同或類似系統(tǒng)/功能的研發(fā)。
-
形成共識。
如果涉及到不同團隊或模塊間的接口改動,或其他會影響其他人的改動,可以邀請相關(guān)團隊或模塊的接口人參與 Review,以對改動形成共識。
-
質(zhì)量把關(guān)。
對于重要的代碼庫,可能會執(zhí)行比較嚴(yán)格的質(zhì)量把控,如果設(shè)置了必須的 Reviewer,這些 Reviewer 也會參與進來。
-
變動告知。
很多情況下一個代碼庫可能只有一個人維護,如果做了些比較特殊的變動,其他人很難發(fā)現(xiàn)。
因此在做一些重要的但是理解起來不那么直接的地方的時候,最好告知一下相關(guān)的研發(fā),以便他們能大概知道發(fā)生了什么。
2.3. 都 Review 些什么
經(jīng)常會有 Reviewer 拿到 MR 不知道該 Review 些什么,其實無論你參與對應(yīng)項目的深入如何,都可以對代碼進行 Review,也鼓勵不同人從不同的深度、角度去幫助 Review。代碼 Review 沒有固定的形式,它更像是一門藝術(shù),唯一的提高辦法就是實際參與進去。
Review 的時候可以從以下幾個方面入手:
1)簡單的 Review
在 CI 通過的情況下,最簡單的 Review 方式可能只需要這樣:
Reviewer:在實際環(huán)境中都驗證過了嗎?Author:當(dāng)然驗證過了
Reviewer:LGTM
這是一種提醒式的 Review。確認(rèn)一句:是否在環(huán)境中驗證過了,或者進一步把能想到的重要的驗收點提出來確認(rèn)一遍。即使是這種最簡單的 Review 實際上也是有價值的,我們很難保證所有研發(fā)都會在提 MR 前實際在環(huán)境中驗證自己所做的修改,也很難保證單元測試、e2e 測試能 Cover 住所有的情況,Reviewer 基本上也不可能都自己去環(huán)境上跑一遍。讓 Author 去確認(rèn)實際上就是提醒 Author 去確保改動至少是真實有效的,尤其是對一些已發(fā)布版本的 Bugfix,一定要提醒實際自測通過。
類似的提醒還包括:相關(guān)的文檔(外部的)是否相應(yīng)更新了、這個改動是否會有兼容性的問題、性能是否有影響。他們的本質(zhì)就是提醒 Author 自己去思考他們可能遺漏的問題。
2)常規(guī)的 Review
代碼 Review 一般都會從代碼風(fēng)格、變量命名、語法統(tǒng)一處入手,當(dāng)然這些應(yīng)該更多的借助于 CI 等自動化手段來保證,但是在相關(guān)流程還不是很完善的前提下還是有必要進行關(guān)注。
此外代碼可讀性、代碼健壯性、代碼可擴展性都是 Review 時關(guān)注的點。每一個關(guān)注的點都依賴于 Reviewer 的實際經(jīng)驗,這里只簡單舉幾個例子:
{ 代碼可讀性 }
代碼是寫給人看的,因為沒有不需要維護的代碼,無論是 Author 自己后續(xù)維護代碼,還是他人接手代碼,能快速地理解代碼邏輯是非常必要的。
代碼 Review 的時候可以關(guān)注以下幾點:
-
變量、方法的命名是否合適,是否真實反映了他們的目的,這方面網(wǎng)上可以找到不少的資料說明。
?
-
實現(xiàn)的邏輯是否已有現(xiàn)成的庫可以替代。
如果有成熟的庫可以使用,盡量不要自己去實現(xiàn),因為可能會引入不必要的 bug。
從我個人的角度,簡潔(大白話就是代碼少)是可讀性一個很重要的指標(biāo)。
?
-
關(guān)于注釋。
代碼注釋不求多,而在于有效,以前也經(jīng)歷過代碼注釋要求至少達到 30% 以上的年代,現(xiàn)在看來過多依賴注釋其實是對代碼質(zhì)量的不自信,好的代碼應(yīng)該盡量做到自解釋。
在實際過程中偶爾能看到代碼邏輯實際已經(jīng)清晰明了,但是用語句不怎么通的英文注釋了一通,最后反而是看懂了代碼才能理解注釋到底說了啥。
因此 Review 的時候,不必要的注釋可以建議去掉。
?
-
不好理解的地方要有恰當(dāng)?shù)淖⑨尅?/p>
代碼中如果有特殊處理、特殊的常量、或者不符合一般用法的邏輯需要特別注釋說明一下。
?
-
代碼的組織。
良好的代碼應(yīng)該有較好的封裝以及層級,使得代碼看起來清晰明了,比如 DAO 層、Service 層。
?
{ 代碼健壯性 }
-
代碼的改動是否會影響其他功能。
-
用戶參數(shù)是否做和細(xì)致的校驗。
-
有沒有 Panic 的可能(針對 Go 的說法)。
-
是否會破壞 API 的兼容性。
{ 可擴展性 }
當(dāng)前的實現(xiàn)方式是否能兼容以后類似的擴展需求。比如在新增接口、API 或者調(diào)整參數(shù)以解決某一問題上,可以考慮是否后續(xù)會有其他類似情況發(fā)生。舉幾個例子:
-
假設(shè)我們需要定義一個 API 接口去獲取一個用戶的某些信息,例如聯(lián)系方式等,我們定義的 API 就不能只返回這些信息,而是應(yīng)該把用戶相關(guān)的信息都返回。
-
假設(shè)我要定義一個參數(shù),雖然當(dāng)前定義成單個元素即可滿足,例如 string, int,但是以后是否會涉及到多個元素的場景,是否定義成 []stirng, []int 是更優(yōu)的。
這里只是舉了有限的一些例子,在實際 Review 過程中,Reviewer 可以根據(jù)自身的經(jīng)驗從各個角度提出優(yōu)化的意見。一般需要重點看看:
-
你看不懂或疑惑的地方。
-
打破你常規(guī)的地方。
-
復(fù)雜的地方。
2.4. 如何進行
Review 過程中鼓勵 Reviewer 大膽 Comment,有不理解的地方,或者覺得不合適的地方都直接表達出來,Author 對 MR 的 每個 Comment 也要做出反饋,無論是展開討論還是簡單的給個 OK 都是有效的反饋。
Review 的過程可以是:
-
Author 在各項確認(rèn)工作完成后,發(fā)起 Review,如果比較急,可以給重要的 Reviewer 發(fā)消息請求幫忙 Review。
-
Reviewer 看到 MR 后應(yīng)該先確認(rèn) MR 的背景和目的,如果不清楚也無法從 MR 中獲取該信息,最好直接和 Author 溝通。
-
Reviewer 直接在 MR 上提出自己的建議或者問題。
-
Author 對每個 Comment 進行反饋,并展開必要的討論。
-
復(fù)雜的話題可以采用線下討論以提高溝通效率。
-
Author 處理完了所有的 Comment,也修改了代碼后,需要在 MR 里 @ 一下相關(guān) Reviewer 告知所有優(yōu)化已經(jīng)提交,如果時間比較急也可以直接和 Reviewer 溝通。
-
Reviewer 確認(rèn)沒問題,給 MR 進行 Approve,一般簡單的回復(fù)是 LGTM(Lood Good To Me),也可以對 Author 的工作進行贊賞,比如 “God Job” 等。
-
Approve 后 MR 由誰來合并這個看自己選擇。
-
如果 Reviewer 提供了很多有用的建議幫助優(yōu)化代碼,Author 也可以禮貌性地感謝一下 Reviewer。
2.5. 關(guān)于 Comment
代碼 Review 很大程度上就是給代碼挑毛病,而且一般預(yù)期挑的越多越好,但代碼是 Author 寫的,很多情況下或多或少會對 Author 造成不適。所以在 Comment 的時候需要盡量注意措辭,尤其是一些主觀的東西,一般以建議的方式給出。當(dāng)然對于原則性的問題,是要堅守質(zhì)量標(biāo)準(zhǔn)的,甚至可以直接 Deny 掉 MR。
另外,參與者也不要吝嗇你的溢美之詞,無論是 Author 還是 Reviewer,在 Review 中發(fā)現(xiàn)了好的地方或好的建議,請給予對方以肯定和贊美,這樣有助于 Review 有效的進行。
2.6. 參與者該抱著怎樣的心態(tài)
2.6.1. Author
首先需要明確一點,是 Author 自己對代碼的質(zhì)量負(fù)責(zé),因此應(yīng)當(dāng)懷著感恩的心去看待堅持認(rèn)真幫你 Review 代碼的 Reviewer,因為并不是所有你加的 Reviewer 都有時間和精力來幫你提高代碼質(zhì)量。
也正式因為 Author 是自己代碼的 owner,所以不要依賴于 Reviewer 去幫你守代碼質(zhì)量的大門,像 “代碼 Review 的時候你怎么就沒看出來”,“這不是你建議我這么做的嗎” 這樣的話千萬別說。Reviewer 只是幫你提高代碼質(zhì)量,因此我們該做的工作都要去做,比如細(xì)致的 Reviewer 可能某些情況下直接提出了代碼優(yōu)化的建議,Comment 時貼上了優(yōu)化的代碼片段,Author 不能直接假設(shè)它一定是能正常工作的,而應(yīng)該對它進行完整的驗證。
對 Reviewer 給出的 Comment,不要有抵觸的情緒,對你覺得不合理的建議,可以委婉地進行拒絕,或者詳細(xì)說明自己的看法以及這么做的原因。有時候一個你覺得不合理的建議可能代表一個新的思考角度,也可能代表 Reviewer 自身代碼能力上的不足,無論是哪個,無論最終是 Author 還是 Reviewer 得到了提高,都應(yīng)該是好事。
2.6.2. Reviewer
Review 代碼既是幫助提高代碼質(zhì)量的過程,也是 Reviewer 提高自己代碼能力和溝通能力的過程。因此應(yīng)該在 Review 的同時保持一個學(xué)習(xí)者的心態(tài),既要發(fā)現(xiàn)對方代碼中的缺陷,也要努力去發(fā)現(xiàn)代碼中的亮點。切記單純以挑毛病的心態(tài)去 Review 代碼。
有不少 Reviewer 在寫 Comment 的時候會猶豫,擔(dān)心自己提出的問題或建議比較“蠢”,因此猶猶豫豫下看完了代碼抱著一堆疑慮最終啥也沒留下。其實在代碼 Review 的時候大可不必有什么心里負(fù)擔(dān),有什么疑惑的、不清楚的地方或者有什么自己的想法,可以直接提出來,有時候一個簡單的 Comment 就可能會激起 Author 和你的 Comment 毫不相干的新思路。再者你即使沒幫 Author 提高代碼,讓 Author 幫你提高思考不也是建不錯的事情嗎。
Reviewer 也不需要去關(guān)注自己的“產(chǎn)出”,并不是一定要提出一堆問題才是好的代碼 Review,Author 代碼寫得很棒也是很正常的,如果從你的角度覺得代碼沒問題,大膽給個 LGTM 甚至是 Approve。
?
總結(jié)
以上是生活随笔為你收集整理的【分享】 codeReview 的重要性的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 单容水箱液位pid控制实验报告_过程控制
- 下一篇: 华为安全HCIP-Security H1