不知不覺間,代碼也寫了二十余載,我已成精了。借著過來人的身份和語氣,有一件事情我一直都特別喜歡吐槽:無論過去多少年,中國的嵌入式軟件開發者群體似乎一直對一個叫做“編碼規范”的東西趨之若鶩,仿佛是什么了不得的武林秘籍,學會了就可以叱咤武林讓讓人不敢小覷;又亦或是什么內功心法,需要每日研讀或與它人細細品讀交流,以求它日可以參透其中奧秘,從此內力大增,用心跳就可以虐死對手。
君不見,曾幾何時《某為編程規范》在網上被廣泛傳抄,互聯網時代雖然無法“洛陽紙貴”,卻曾經引得某公司的公關部門到處發函讓站長們刪帖;時過境遷,雖然某為的編程規范也不至于熱度全無,但對冠名于國外大廠大公司的編碼規范的追捧卻已悄然成為當下的熱門——仿佛如果說不出自己使用的規范來自哪個大門派,都不好意思跟人家打招呼。
可拉倒吧!
在兄弟們浪費太多時間之前,可曾了解過自己苦苦追尋和模仿的究竟是個什么東西?
【編碼規范的本質是什么?】
要理解編碼規范的本質,其實并不復雜:
編碼規范是在一定范圍內強制推行的編碼習慣;這里的編碼習慣通常來自于對團隊有控制力的一個或者少數幾個人。
這里,你會很容易注意到三個關鍵字:“一定范圍”、“強制推行”和“編碼習慣”。抓住這三點,編碼規范的本質就像“任意不在同一直線上的三點確定一個平面”一樣——沒得跑了。
首先來說說這個“編碼習慣”,其實很好理解,它就是字面意思——一個人寫代碼時候的某種習慣,高情商叫風格,低情商叫“我就愛這么干,別問我為啥,我要么不知道,要么等我編個理由告訴你”。總之呢,編碼習慣帶有強烈的主觀性、基本上可以認為缺乏強有力的客觀依據,在穩定性和一致性方面其實就是水中花鏡中月——不能說完全沒有,只能說毫無可信度。
不信么?今天你看了一個大牛的代碼,覺得:
“哇!好牛逼”,
“大牛這么做一定有什么深意”
然后不自覺的就學著人家的編碼規范來了。過了幾天,你可能又碰到了另外的大牛,或者是什么明星開源項目……咋說呢……如果用男女關系來形容兄弟們的行為,那就是妥妥的渣男/渣女——沒得洗。
你跟我說說,哪兒來的穩定性和一致性?還不如先問問“你是誰的粉”比較靠譜。
很多時候,一個程序員自己的編碼習慣可能一輩子都沒有鯉魚躍龍門——成為編碼規范的機會;但如果有朝一日,你滿足了以下兩個條件,你的編碼習慣就是妥妥的編碼規范了:
擁有了一個完全由自己掌控的團隊或者項目;
擁有了執行決定的強制力;(比如KPI審核,扣工資之類)
此時,只要你樂意,完全可以在“你控制的范圍內”“強制”推行你自己的編碼習慣——恭喜你,一個只屬于你的編碼規范就誕生了。
【編碼規范的“原罪”】
搞懂了編碼規范誕生的原因,接下來很自然的,就要聊一聊伴隨編碼規范一起誕生的“原罪”了。
要理解什么是編碼規范的原罪,首先必須要講清楚“編碼規范”(或者說“遵守編碼規范”)的意義。然而,有些東西你非要向字典一樣去從正面解釋往往非常抽象,但稍微打個比方,就簡單明朗了——實際上:
編碼規范的作用幾乎完全等效于人類自然語言文字中的書法。
簡單說,編碼習慣就是關于“你如何寫字的”,而編碼規范就是“一群人所遵守的書法風格”。這么一比方,也許你立馬注意到了:
無論是編碼規范還是編碼習慣,都只跟描述“你寫字丑不丑”、“漂不漂亮”的一個“主觀性非常強的”、甚至還帶有“藝術性玄學”的評價標準有關;
我們日常寫代碼其實可以類比為寫文章,這意味著:
你可以用非常漂亮的手寫體寫出狗屁不通的文章;
你也可以在趕時間的情況下,用一種只有自己看得懂的方式,快速而高效的寫出優秀的作品;
書法除了草書,往往暗示著——費時間;何況草書往往暗示著,除了那幾個評論家,普通人基本看不懂。
書法好壞和寫文章所需的遣詞造句的技法,以及文章整體的修辭、結構安排完全無關。
說的再直白一點:當你在追求“如何寫出精修文章時”,追求“書法”,是淺薄的,而且毫無意義的。當你在追求如何寫出好的程序時,你需要的是數據結構、算法、操作系統、軟件工程、設計模式、開發思維之類的知識,而不是關于如何把代碼寫的多么漂亮,多么“規范”的書法——或者說表面功夫。認真說起來,連這里“怎樣算作代碼寫的規范”,從一開始就只是某幾個人的主觀概念罷了。
正如景秀文章往往也是用賞心悅目的書法寫出來的;注重表面的編碼規范也并非是什么大罪大惡需要我們棄之如糞土。要知道這其中區別,就必須要談一談編碼規范的原罪。
原罪1:膚淺引戰的導火索
正如我在之前一篇文章《真刀真槍模塊化(1)——一本糊涂賬》所提到的那樣:
……讀懂一段程序,實際上就是要通過死的代碼邏輯去反推模塊構作者的思維,這是一個逆向過程,這是一個人與人之間用代碼進行間接交流的過程,當邏輯本身較為復雜時,顯然比將自己的思維直接翻譯成程序(重新開發一個)更為困難。
傻孩子,公眾號:裸機思維真刀真槍模塊化(1)——一本糊涂賬
這里,我提到了一個關鍵的事實——閱讀他人代碼是非常耗時和困難的。這樣的事情無時無刻不在發生:當我們拿到一段代碼時,想通過了解它的內容來判斷好壞幾乎是不可能的——這不光意味著你要花費時間去閱讀它,可能你根本不想去閱讀,或者根本沒有這樣的時間去閱讀。此時,要想判斷一段代碼的好壞就只能通過非常表面的東西來進行了——是的,就是看你寫的字漂不漂亮。
如果明確知道這是“名人大家”的作品,或是出自某個大廠的作品,事情就變得非常簡單:只要學習歷來文人是如何在同行面前顯示自己學識淵博的方式——花式吹就行了。
如果要評價的對象是同輩的作品,或是某個來源不明的作品,大家就一下開始“審慎起來”,仿佛瞬間化身為嚴肅的藝術評論家——在嚴肅而充滿理性的批判聲中,自己“高超水平”和“恨鐵不成鋼的惋惜”躍然紙上。
嗚呼哀哉,文人相輕,這味兒太沖了。
原罪2:似是而非
前面我們說過,編碼規范的本質是編碼習慣,編碼習慣擁有非常強的主觀性,因而缺乏客觀標準。然而,這話只說了一半,事實上,并不矛盾的一點是,如果某個編碼習慣出自于“較為嚴謹認真”的人之手,這樣的編碼習慣也便“主觀的”擁有了一定的客觀性——這完全是由提出的人的特性而決定的——因此依然是主觀的。這可就頭疼了。因為這些“嚴謹認真”的人,他們在養成編碼習慣時,往往的確會有理性的思考,不光能說出所以然,而且似乎可以說服很多人,讓大家覺得
“這樣做很有道理”甚至“不這么做就是錯的”
的判斷。問題是:
這些“嚴謹大佬”們做出思考的背景是不同,而人們討論和傳播編碼規范的時候往往會丟棄這些背景信息而將其“泛化”——或者說無限制的擴大適用范圍;
很多作為某一編碼規范規則在背后的支撐邏輯,我們可以說它是“正確的”,但遺憾的是,它的正確“并不意味著其它做法是錯的”——事實上,有很多規則所服務的邏輯實際上存在很多“同樣正確、且平等的正確的競爭者”。
關于這點,其實并不難理解,比如,假設我們想解決一個問題A,那么可能有1,2,3,……很多個解決方案,這些方案中可能會存在一些“同樣正確且各有優缺點的”。從另外一個角度來看,對于一個已知的“規則或者行為”,你往往可以找到不止一種原因和動機去解釋它。所以,結合以上兩個方向的例子,我們要明白,很多事情都不是“非黑即白”的,尤其是編碼規則的好壞、成因、收益這種極端主觀的事情。
編碼規范的信徒們,往往視其它規范(甚至是某一個規范的變種)為異端,定要除之而后快,表現為與他人進行無意義的論戰、不說服他人加入自己的陣營就決不罷休,甚至上升到人身攻擊等等……
原罪3:遮羞布
正因為評價它人代碼的閱讀代價太高,而憑借“眼緣”去評價它人“字太丑”簡單且可行,因此,對很多人來說,追求“書法”而不是具體的“寫作文能力”就成了“快速提高代碼質量”的捷徑——這里的代碼質量,很多時候也僅僅只是“是否好看”了……
【C語言編碼規范的“甜”和“咸”】
如果書法大家云集流派眾多,C語言的編碼規范也是有“門派”的,比如大家熟悉的Linux派、微軟派……(此處省略1W字)。然而,無論門派多寡,其實都可以在一個“編碼規范光譜”中為其找到一席之地。
在光譜的最左邊是名為“純粹追求美觀”的極點、在光譜的最右邊是名為“純粹追求功能性”的另一極。實際上如今你所熟悉的編碼規范,基本都位于兩級中的某一位置。
“純粹追求美觀”,顧名思義,代碼寫出來要眼睛看著舒服。需要特別強調的是,這里的看著舒服與“代碼的可讀性”完全是兩回事。
純粹追求美觀的杰出代表是Linux編碼規范——它所追求的是純粹小寫所帶來的那種和諧而統一的美;它基本不對函數、變量名、類型名做任何的區別(甚至是非常數的宏);為了解決小寫單詞缺乏“節奏”的問題,而在單詞與單詞之間簡單的引入“_”完事。
這種美學就好比最優質的牛排,只需要輔以簡單的海鹽,進行簡單的烹飪就能發揮牛排最原始的美味;這就好比,新鮮的生蠔,只需要擠上幾瓣檸檬就可以釋放出最大的鮮甜……
正是由于Linux這種純粹追求視覺上的和諧而不“詭辯”自己有如何功能上的便利,受到眾多“返璞歸真”老鳥的狂熱追捧——我要的就是簡潔的美,其它都在我心間。
“純粹追求功能性”,顧名思義,就是以犧牲一定程度的“美感”而換取某種功能上的便利。實際上,完全犧牲美感的編碼規范幾乎沒有,但很多商用協議棧的編碼規范或多或少都有著明確的功能追求。
典型的是匈牙利變量命名法,它的特點是為每一個變量追加必要的類型信息,從而提高變量名的信息攜帶量——最終嘗試提高代碼的可讀性。在Linux玩家的眼里,匈牙利是真的丑;同時作為一個如入鮑魚之膚久而不聞其臭的匈牙利變量命名法玩家,我也只是“習慣了”這種用法,你要說我覺得它有多美,那也絕對是扯淡。有意思的是,匈牙利變量命名法往往會與駝峰命名法攪和在一起,這讓純粹的駝峰信徒頗為不爽——因為駝峰可以說是“美的”,但你非要粘上一些類型標簽——就好比在布丁的蜂蜜澆頭上發現了蒼蠅一樣惡心。
公平的說,匈牙利所附加的信息的確有助于提升代碼的可讀性。至于美不美,可以完全拋在腦后。
另外一類“追求功能性”的編碼規范就是各類DSP、視頻、音頻、數學相關的協議棧,它們純粹為了方便API的使用,嘗試在變量、函數以及類型名稱上附加大量的信息,以描述API的參數類型、函數所代表的的運算功能、以及其它相關專業方向才會理解的特性屬性等等——這樣的信息追加,造就了猶如喀斯特地貌一樣的奇觀——用是好用,美不美,就不好說了。這類協議棧的典型是鼎鼎大名的Dolby的音頻庫。
對普通人來說,一般我們使用的編碼習慣都處于這兩級的中間地帶,這不光因為很多時候我們同時會有“看著順眼”和“提供額外信息”這兩種追求,更主要的原因是:編碼規范的本質是書法,對我們所使用的書法起決定作用的是“審美”,而每個人不同階段的審美很難保持一成不變。當我們因為工作關系游走于不同的團隊而被迫服從的編碼規范時,久而久之……如邯鄲學步,自己的“初心”可能早就被染成了“別人的顏色”……
【編碼規范,怎么做才對?】
知道了編碼規范的本質和原罪、討論了編碼規范的兩個極端風格,那么我們普通人應該如何對待它呢?
字寫的好看,是一種展示“認真態度”的方式;努力寫出漂亮的代碼無可厚非;
切記不可喧賓奪主,在本意是追求“如何寫出優秀作文”的時候,注意力過多的被“如何寫出漂亮字”的編碼規范所抓住,浪費不必要的時間;
不要把編碼規范上升成宗教信仰——哪怕你是無意識中這樣做的;
記住:優秀的程序員可以在任何編碼規范上隨意切換——這是你游刃有余的一種表現。
如果想討好一個人,贊揚他的書法;
如果一個群里的人讓你討厭,可以在退群之前,可以故意挑起關于編碼規范孰優孰劣的宗教戰爭——如果碰巧他們都是同一個宗教的信徒,則嘗試發起關于“怎樣才是正統”的討論。如果你喜歡一個群,就切記不要這么做。
在自己可控的范圍內——比如自己的開源項目里,隨意的使用自己的編碼規范。如果要跟他人合作,最好寫清楚自己的習慣,并且保持包容的心態——因為,請記住:
編碼規范的制定者往往會被所有人盯著,等著你的永遠是“你自己的規范你自己都沒遵守”,而不是“你的規范真好”的贊賞;
對任何你訂立的規則,你寫下來的只是你心目中的“默認情況”,而沒寫來的是大量你自己覺得合理的“特殊情況”——在你心中,除了“少數”特殊情況外,我們都應該按照“默認情況”來處理——可惜,這里的“少數”往往超出你的想像;
不要認為別人質疑你的編碼規范就是在罵你、質疑你或者找茬——哪怕大部分情況都是這樣;
同理,盡可能遵守它人的編碼規范,來展示自己對它人的尊重。看到“特例”不妨一笑了之。
干點正事吧!
【說在后面的話】
編碼規范展現的是一種“認真的態度”,但它不是“能力和質量”本身。區別你要追求的是“書法的”編碼規范,還是“思維的”編碼原則。尊重他人從不貶低他人的編碼習慣開始;團隊合作從嚴格遵守編碼規范開始。不要浪費太多時間,舒服就好。
責任編輯:haq
-
編碼器
+關注
關注
45文章
3638瀏覽量
134426 -
編程
+關注
關注
88文章
3614瀏覽量
93686
原文標題:編碼規范可能只是一塊遮羞的破布。。。
文章出處:【微信號:A1411464185,微信公眾號:multisim】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論