創(chuàng)業(yè)團隊如何制定可執(zhí)行的代碼規(guī)范

原文: 創(chuàng)業(yè)團隊如何制定可執(zhí)行的代碼規(guī)范

回想起來自己工作這么些年,也經(jīng)歷了不少團隊,經(jīng)歷的項目更不算少了, 但是要說到代碼規(guī)范, 問我我經(jīng)歷的這些代碼規(guī)范是不是滿意,我不得不如實回答:不是很滿意。當然我自己的代碼規(guī)范和風格也沒有完全固化下來,近一年左右也開始關注到這個問題,為了讓自己的代碼風格能逐漸固化,我會專門用一個筆記來記錄一些可能自己會糾結(jié)的寫法,這樣做了以后明顯能感覺到自己代碼風格的飄忽程度有所收斂。恰巧公司負責的項目也需要整理代碼規(guī)范,正因如此我開始思考如何制定可執(zhí)行的代碼規(guī)范這個問題。
提到團隊的代碼規(guī)范,不止我經(jīng)歷過的,我和一些朋友也有聊過, 有微軟那個級別的,也有BAT這種級別的,項目大的也有,小的亦很多。其中不乏規(guī)范的做的比較好的,有規(guī)范、有工具、還會有Code Review來保證。但是大公司規(guī)范和流程真的適合所有團隊嗎?我所看到的是大部分團隊參照某某公司的規(guī)范和流程,定義了一個非常嚴格的標準,然而實際上并沒有嚴格實施下去或者沒有持續(xù)實施下去。最后都會甩鍋給“歷史包袱太重”、“開發(fā)人員太多太雜難以推廣”這樣的理由。
近半年到一年在代碼規(guī)范這一塊我主要思考如何在中小團隊沒有代碼規(guī)范的基礎上制定代碼規(guī)范。根據(jù)自己的思考也正在組內(nèi)逐步實踐,從目前實踐情況來看我是比較滿意的,所以把自己觀點寫出來,希望能對跟我有同樣困惑的人有些幫助。

代碼規(guī)范不應該被定為KPI

所有的規(guī)范,包括但不限于代碼規(guī)范,都會包含規(guī)范制定、規(guī)范推廣執(zhí)行、規(guī)范修正的過程。 其中規(guī)范的推廣和執(zhí)行通常是最難的(這就是為什么有很多流程文檔,但是流程還是非常混亂的原因),而制定了什么樣的規(guī)范直接決定了推廣執(zhí)行的難度,所以我們先從代碼規(guī)范的制定說起。
大部分團隊應該都是有KPI的,而且一般重要的事情都會被定成KPI, 所以有些團隊為了強調(diào)代碼規(guī)范, 將其定為某些員工的KPI,這樣重視代碼規(guī)范行為我是非常欣賞的,但是我不認同,因為我認為代碼規(guī)范不應該是一個文檔, 代碼規(guī)范應該是一種行為, 一種持續(xù)的行為,而KPI是要求可以量化有明確目標的。若把代碼規(guī)范當作KPI, 背了KPI的員工為了讓KPI可量化, 通常情況會寫出來一個代碼規(guī)范文檔,眾所周知文檔最可 量化的當然是頁數(shù),故最終可能會產(chǎn)出一個幾十頁的代碼規(guī)范,它可能是結(jié)合了Google、Facebook、Tencent等等大公司的代碼規(guī)范,幾乎面面俱到,看起來就很高大上。
代碼規(guī)范文檔出來了,KPI看起來也完成得不錯,那然后呢?如果我們把代碼規(guī)范理解為一種行為,那這文檔就僅僅只是一個行為準則,它就像是一部法律,要求大家都要如何做,所以接下來更重點的工作應該是去讓這些文檔落地,讓大家理解認可執(zhí)行它。并且還需要有相應的監(jiān)督機制、審查機制來保證大家確實按規(guī)范在寫代碼。但是后面這些,也就是整個代碼規(guī)范實施最難的點,要量化又極其不易。能如何量化呢?量化推廣程度?量化大家對各條代碼規(guī)范的理解透徹程度?難道用考試來量化嗎?這就是把代碼規(guī)范設定成KPI的尷尬, 為了讓KPI看起來豐滿, 產(chǎn)出了一個豐滿的規(guī)范, 而對于整個過程中最難的落地執(zhí)行環(huán)節(jié), 豐滿的規(guī)范為其增加了阻力。
以前我對于代碼規(guī)范的理解是也是越豐富越好,但是在近半年推廣代碼規(guī)范的過程中我開始青睞簡單一些的代碼規(guī)范,因為我相信大部分人會贊同:一個被100%徹底執(zhí)行了的40分代碼規(guī)范應該是好于一個被執(zhí)行了40%的100分代碼規(guī)范。

制定代碼規(guī)范要循序漸進

這個觀點可能會更比較多人的看法不太一樣, 因為很多人都認為規(guī)范應該前期就定下來,而且盡可能面面俱到,否則后面定規(guī)范容易背上歷史包袱。前期就應該定規(guī)范的這個觀點我比較認同,首先我們拋開你們團隊已經(jīng)有非常完善代碼規(guī)范這種情況,因為如果是那樣,你只需要按原有規(guī)范執(zhí)行即可。這里主要討論新項目沒有規(guī)范的情況下怎么做,我們可以復盤一下新項目開始階段,通常情況新項目需求節(jié)奏都會非常快,基礎框架、基礎組件、大批量業(yè)務需求要開發(fā),又因為是新項目,通常不會有特別多的人力投入,這種情況下,一個很嚴格冗長的代碼規(guī)范,要求大家在拼命跑的過程中還要去理解執(zhí)行你的規(guī)范,可能性大嗎?所以這個時期的代碼規(guī)范需要非常簡單易于理解,要在所有人即使在趕需求,也能忍受的范圍內(nèi)制定規(guī)范。這個階段最急迫的需求是用簡單的代碼規(guī)范讓大家養(yǎng)成習慣,提升意識,宣告這個項目是有規(guī)范的。
我們拿前端項目來舉例,首先應該先保證JS代碼風格是對的,其次可能根據(jù)技術選型不同(例如Angular,React),要遵循另外一批Best Practice。按上述思路,我會在前期只要求大家JS代碼格式規(guī)范就行了。因為把各種Best Practice一股腦的全丟進去容易繞暈大家。 如果你真的舍不得那些Best Practice,我建議將其列為建議級別的,先不做必須,必須的條目盡可能精簡。

制定代碼規(guī)范需要"獨裁"

上面一段提到代碼規(guī)范應該循序漸進,但是簡單的規(guī)范從何而來呢?之前看到過的一種做法是:團隊內(nèi)大家一起討論,民主決定某一些規(guī)范的細節(jié),因為這樣可以出來一個適配這個團隊的代碼規(guī)范。 這聽起來很美好,非常民主,大家很平等,但是回想一下以前這么做的結(jié)果是什么?我猜應該會有很多人又回憶起“大括號應不應該換行”、“else是否應該換行”、“是否允許空兩行”、“JS結(jié)尾帶不帶分號”等等類似的爭論吧,然而這些爭論是有必要的嗎?說白了,大部分爭論找的理由都只是在為自己的代碼習慣爭取更多空間。這樣的爭論還只是“民主”引發(fā)問題的開始,更嚴重的是這會在所有開發(fā)人員心中形成一種“規(guī)范是可以商量和討論的”心理暗示,這必對后續(xù)規(guī)范的執(zhí)行成為阻礙,特別是一些本身就有爭議的點,總會有人伺機反撲。另外,“民主”的規(guī)范其實很難做到讓所有人心理上平衡,例如可能會讓B開發(fā)覺得自己在遵從A開發(fā)的習慣,即使這種感覺可能不是那么強烈,它也會變成規(guī)范執(zhí)行的阻力。
正因為上述原因,我非常建議制定規(guī)范時“獨裁”。我們的目標很清晰,就是要求代碼寫法一致,“獨裁”的基礎上可以選擇一個第三方的標準,例如細的條目可以完全選擇Google或者Facebook或者其他一些大公司的標準(當然可能還需要考慮我上面提到的循序漸進,做裁剪,但是規(guī)則細則不要再去討論和挑戰(zhàn))。首先可以保證的是這些規(guī)范不會有太大的問題,跟著做不會犯大錯;其次,“獨裁”使用的規(guī)范來源于第三方,對團隊內(nèi)所有人公平;最后,這樣的規(guī)范和行業(yè)更親近。
我在我們的前端項目里面就選擇了StandardJS的規(guī)范,StandardJS的出現(xiàn)初衷也正是為了解決上述“民主”引發(fā)的問題。除此之外,還有一個好處是這些第三方規(guī)范的成熟不只是規(guī)范本身,它的配套工具會成熟很多,可以節(jié)省自己很多成本。

代碼規(guī)范從“立法”到“執(zhí)法”

上面我們已經(jīng)討論了如何建立代碼規(guī)范,主要強調(diào)了代碼規(guī)范不應只是一紙空文代碼規(guī)范要循序漸進代碼規(guī)范的制定需要“獨裁”。這些都屬于“立法”過程,接下來要討論的必然是“執(zhí)法”,代碼規(guī)范的“執(zhí)法”主要需要關注兩點,一點是“違法”行為的判定,另一點是“違法”行為的責任追究,也就是代碼規(guī)則檢查以及發(fā)現(xiàn)不符合規(guī)范的代碼應該由誰來負責。
代碼規(guī)則檢查通常直接使用現(xiàn)有成熟工具就好,例如前端開發(fā)常用的ESLint,現(xiàn)在各種語言都有各自比較成熟的工具,我這里想強調(diào)的是幾個檢查代碼的時機,一是寫代碼的時候,這是源頭,配置一個好的IDE檢查規(guī)則能從源頭避免不規(guī)范的代碼。二是提交時候,通常是設置git/svn的hooks(PS: git的hooks在2.9.0之前相當?shù)碾y用,如果你用的版本低于2.9.0,可以考慮升級并配置代碼檢查的鉤子)。三是CI的時候,這是最后一關,可以保證合流以后的代碼不出現(xiàn)規(guī)范的問題。只要在上面三個點嚴格執(zhí)行了,不規(guī)范的代碼幾乎已經(jīng)無處可藏。
“違法”行為判定盡可能通過工具來判定,那如果出現(xiàn)了庫里面提交了不合規(guī)則的代碼應該由誰去改呢?如果有CI,那只需要增加提交構建,即可在push后的第一時間揪出違規(guī)者。如果沒有CI,我建議是先建立CI,如果實在沒有,那可以考慮最后提交代碼負責制,最后提交代碼的人可以去找這份代碼是merge了誰的,追溯到上游把“鍋”丟出去,最終找到違規(guī)者并要求改進(不限于代碼的改進,更重要的是各種代碼檢查環(huán)境的配置)。這樣的定義可以讓所有開發(fā)知道遇到問題以后該如何走下一步,我認為是非常有必要的。
說到這里我猜必然有讀者想到了Code Review,實際上Code Review不應該是去關注代碼風格的,所有到Code Review環(huán)節(jié)的代碼必然是要過了代碼風格檢查的,Code Review主要關注的是代碼結(jié)構設計和代碼邏輯,它是在代碼規(guī)范上一層的東西。如果你的團隊在使用Code Review來保證代碼規(guī)范,那你們可能需要進一步完善自己的代碼規(guī)范檢查工具。

總結(jié)

代碼規(guī)范的好處大家都知道,但是任重道遠。真正去推行代碼規(guī)范的人,如果按我上面說的幾點去做,可能會有各方面的壓力,特別是上面提到的“獨裁”和“執(zhí)法”兩點,但是從我自己的實踐經(jīng)驗來看,想象中的壓力小于實際,主要還是需要向同事們解釋清楚各種做法的理由,得到理解和支持。為了避免前期的推行的壓力過大,可以考慮裁剪規(guī)則(特別是在沒有很好代碼規(guī)范文化的團隊內(nèi)),因為提升團隊人員意識和養(yǎng)成代碼規(guī)范的習慣應該是最最首要的任務,這兩點有了以后,再逐步的把要求提高,應該會容易得多。這個過程有困難,但是我堅定的認為這是值得的。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容