別人都說我們是“搬磚”的碼農,但我們知道自己是追求個性的藝術家。也許我們不會過多在意自己的外表和穿著,但在我們不羈的外表下,骨子裡追求著代碼的美、繫統的美、設計的美,代碼規範其實就是對程序美的定義。但是這種美離程序員的生活有些遙遠,盡管編碼規範的價值在業內有著廣泛的共識,在現實中卻被否定得一塌糊塗。工程師曾經最引以為豪的代碼,因為編碼規範的缺失、命名的草率而全面地摧毀了彼此的信任,並嚴重地制約了高效協同。工程師一邊吐槽別人的代碼,一邊寫著被吐槽的代碼,頻繁的繫統重構和心驚膽戰的維護似乎成了工作的主旋律。
那麼如何走出這種怪圈呢?眾所周知,互聯網公司的優勢在於效率,它是企業核心競爭力。體現在產品開發領域,就是溝通效率和研發效率。對於溝通效率的重要性,可以從程序員三大“編程理念之爭”說起:
— 縮進采用空格鍵,還是 Tab 鍵。
— if 單行語句需要大括號,還是不需要大括號。
— 左大括號不換行,還是單獨另起一行。
在美劇《硅谷》中,你也許會記得這樣一個經典鏡頭:主人公Richard 與同為程序員的女友分手,理由是兩人對縮進方式有著不同的習慣,互相鄙視著對方的 code style。Tab 鍵和空格鍵的爭議在現實編程工作中確實存在。《阿裡巴巴 Java 開發手冊(第 2 版)》(以下簡稱“《手冊》”)明確地支持了 4 個空格的做法,如果一定要問理由,那麼沒有理由,因為能夠想出來的理由,就像堅固的盾一樣,總有更加鋒利的矛會戳破它。隻想說,一致性很重要,無邊無際爭論的時間成本與最後的收益是成反比的。
if 單語句是否需要大括號,也是爭論不休的話題。相對來說,寫過格式縮進類編程語言的開發者,更加習慣不加大括號。《手冊》中明確,if/for 單語句必須加大括號,因為單行語句的寫法,容易在添加邏輯時引起視覺上的錯誤判斷。此外,if 不加大括號還會有局部變量作用域的問題,詳見《碼出高效:Java 開發手冊》。
左大括號是否單獨另起一行?因為 Go 語言強制不換行,在這點上,“編程理念之爭”的硝煙味沒有那麼濃。如果一定要給一個理由, 那麼換行的代碼可以增加一行,對於按代碼行數考核工作量的公司員工,肯定傾向於左大括號前換行。《手冊》中明確,左大括號不換行。這些理念之爭的本質就是自己多年代碼習慣生的繭,不願意對不一樣的風格妥協,不願意為了團隊的整體效能提升而委屈自己。其實,很多編程方式客觀上沒有對錯之分,一致性很重要,可讀性很重要,團隊溝通效率很重要。有一個理論叫帕金森瑣碎定律:一個組織中的成員往往會把過多的精力花費在一些瑣碎的爭論上。程序員天生需要團隊協作,而協作的正能量要放在問題的有效溝通上。個性化應盡量表現在代碼可維護性和算法效率的提升上,而不是在合作規範上進行糾纏不休的討論、爭論,最後沒有結論。規範不一,就像下圖中的小鴨子和小雞對話一樣,言語不通,一臉囧相。雞同鴨講恰恰戳中了人與人之間溝通的痛點,自說自話,無法達成一致。再舉個生活中的例子,交通規則中靠左行還是靠右行,兩者孰好孰壞並不重要,重要的是必須在統一的方向上通行,表面上限制了自由,但實際上保障了公眾的人身安全。試想,如果沒有規定靠右行駛,那麼路況肯定擁堵不堪,險像環生。同樣,過分自由隨意、天馬行空的代碼會嚴重地損害繫統的健康,影響到可擴展性及可維護性。
為了幫助開發人員更好地提高研發效率,阿裡巴巴集團基於《手冊》內容,獨立研發了一套自動化 IDE 檢測插件。該插件在掃描代碼後,將不符合《手冊》的代碼按 block/critical/major 三個等級顯示在下方;在編寫代碼時,還會給出智能實時提示,告訴你代碼如何編寫可以更優雅、更符合大家共同的編程風格;對於歷史代碼,部分規則實現了批量一鍵修復功能。此插件已經在 2017年杭州雲棲大會上正式對外開放並提供了源碼,下載地址為https://github.com/alibaba/p3c。
第2版前言
《阿裡巴巴 Java 開發手冊(第 2 版)》(以下簡稱“《手冊》”)是阿裡巴巴集團技術團隊的集體智慧結晶和經驗總結,經歷了多次大規模一線實戰的檢驗及不斷完善,公開到業界後,眾多社區開發者踊躍參與,共同打磨完善,繫統化地整理成冊。在第 1 版基礎上,認真傾聽讀者反饋,學習開源社區的詳細建議,增加前後端規約,發布錯誤碼解決方案,修正架構分層圖例等相關內容,涉及 59 條新規約,修正 202 處原有規約,完善 8 個示例,是面向業界 3 年以來更為完善的版本。
現代軟件行業的高速發展對開發者的綜合素質要求越來越高,除了編程知識點,其他維度的知識點也會影響到軟件的最終交付質量。比如,五花八門的錯誤碼導致排查問題困難重重,數據庫的表結構和索引設計缺陷帶來繫統架構缺陷或性能風險,工程結構混亂導致後續項目維護艱難,沒有鋻權的漏洞代碼易被黑客攻擊等。因此,《手冊》以 Java 開發者為中心視角,劃分為編程規約、異常日測試、安全規約、MySQL 數據庫、工程結構、設計規約七個維度,再根據內容特征,細分成若干二級子目錄。
另外,依據約束力強弱及故障敏感性,規約依次分為【強制】、【推薦】和【參考】三大類。在延伸信息中,“說明”對規約做了適當擴展和解釋,“正例”表示提倡的編碼和實現方式,“反例”表示需要提防的雷區,以及真實的錯誤案例。
《手冊》的願景是碼出高效,碼出質量。現代軟件架構的復雜性需要協同開發完成,如何高效地協同呢?無規矩不成方圓,無規範難以協同,比如,制定交通法規表面上是要限制行車權,實際上是保障公眾的人身安全。試想,如果沒有限速,沒有紅綠燈,誰還敢上路行駛?對軟件開發來說,適當的規範和標準絕不是消滅代碼內容的創造性、優雅性,而是限制過度個性化,以一種普遍認可的統一方式一起做事,提升協作效率,降低溝通成本。代碼的字裡行間流淌的是軟件繫統的血液,質量的提升是盡可能少踩“坑”,杜絕踩重復的“坑”, 切實提升繫統穩定性。
我們已經在 2017 年杭州雲棲大會上發布了配套的“Java 開發規約 IDE 插件”,下載量達到 160 萬人次,阿裡雲效也集成了代碼規約掃描引擎。2018 年,我們發布了 36 萬字的配套詳解圖書《碼出高效:Java 開發手冊》,該書秉持“圖勝於表,表勝於言”的理念,深入淺出地將計算機基礎、面向對像思想、JVM 探源、數據結構與集合、並發與多線測試等知識客觀而立體地呈現出來,緊扣學以致用、學以精進的目標,結合阿裡巴巴實踐經驗和故障案例,與底層源碼解析融會貫通、娓娓道來。《碼出高效:Java 開發手冊》和《手冊》圖書出版所得收入均捐贈公益事業,希望用技術情懷幫助更多的人。