標籤:

代碼的體格

Steve Yegge在他特立獨行的作品《程序員的吶喊》中寫道:「我堅信代碼最大的敵人就是體格」。不過他過於自大了,以為這只是像他那樣牛逼的程序員才擁有的少數派觀點;又或者說他過於悲觀,以為程序員的世界還在拼代碼的肌肉男臆想中。殊不知只要是曾經掙扎在龐大代碼庫泥潭中的程序員,就不會盲目崇拜代碼的大塊頭。

可惜,「知行合一」非聖人不可以做到,夢想的光芒常常難以照進現實的陰影。要縮小代碼的體格,似乎比減肥還要艱難。軟體系統像一條貪吃蛇,吃掉一切功能,最後越變越長,在局限的空間里再也無法做到從容的轉折騰挪,最後活活困死。偏偏還有人以能掌控千萬級代碼的軟體系統為榮。——「兄弟不才,做過一系統,代碼達到了兩千萬行,真是一場噩夢啊!」,程序君一邊搖頭作痛苦狀,噓聲嘆氣,但察其眼角眉間,藏不住的卻是得意和炫耀。

因而,我們一邊在憤慨代碼日益膨脹的體格,一邊又在做著堆代碼的增肥工作。軟體從來都不是一個人寫完的,需求也從來不會穩定不變,於是乎出現了超過數個屏幕的分支語句,出現了大量注釋過的代碼殘骸,於是乎有了拷貝粘貼,程序員漸漸開始降低壞代碼的容忍度,開始得過且過。

面對日益膨脹的代碼體格,Steve的吶喊是換語言,因為他是Ruby粉和Python粉的緣故,恨不得把所有系統都換成Ruby或者Python,要麼就是Lisp。作為Scala粉的我,當然也恨不得所有Java項目都換成Scala。讓我再寫啰嗦的Java代碼,真是痛不欲生,生不如死啊。支持了lambda的Java 8也許還能挽救我,但我還是鍾情Scala。

太天真了!首先是換不了,其次是換了也沒用。你真以為換語言如換刀,寶刀在手,就能割去那些臃腫的代碼,還代碼一個苗條身材?——你以為是抽脂啊!Ruby也可以寫出爛代碼,Java也能寫出漂亮的程序,關鍵不在於語言。正如武林高手比武並不在於刀劍的利鈍,要分出武功高低,根本還是功力和招式。只有同等高手之間的廝殺,手握一柄利器才能成為制勝法寶。

代碼的臃腫關鍵還在於分解與去重。Unix大嗎?大,而且必須大。但它又很小,因為它以內核形式確立了系統的邊界,同時遵循KISS原則,將大功能分解為小程序,每個小程序只能完成一個功能,任何複雜的操作都必須分解成一些基本步驟,由這些小程序逐一完成,再組合起來得到最終結果。分解的一個難題是如何定邊界,換言之就是如何做到「高內聚、松耦合」。另一個難題在於組合,即該如何把這些分解的細小功能再糅合起來,形成一個整體。這也是為何Micro Service被鼓吹了多少遍,仍然有人保持觀望態度的原因。

若說掌握分解這門技藝的高手中高手,還得數庖丁這哥們,「彼節者有閑,而刀刃者無厚,以無厚入有閑,恢恢乎其於游刃必有餘地矣,是以十九年而刀刃若新發於硎。」眼睛都修鍊成了X光,能夠透過牛皮看清骨肉經絡,以至於能夠無厚入有閑,像舞蹈一般變屠牛為行為藝術,舉手投足間,瀟瀟洒灑地把牛給宰了,還揮揮衣袖,不帶走一點血。對軟體系統的分解,我們能做到像庖丁那般識破依賴,判斷「有閑」之節者,進而做到合理解耦嗎?

去重的根本其實還是分解,粒度可以是函數、類、模塊、子系統。程序員需要有潔癖,重複就是最大的dirty,可惜打掃衛生需要付出。寫代碼是件勞心勞力的事兒,總會有人偷懶的。Deadline又是一把懸在程序員頭上的達摩克利斯之劍,在急迫的催促聲中,程序員尋找到了心裡安慰,因為時間是允許降低質量的最完美借口。——當然,時間也是最殘忍的。程序員乾的是刀口舔血的生活,出來混,遲早是要還的。程序世界,就是佛家所謂的「因果世界」啊。

去重的關鍵並不在於技巧(程序員都不是傻子,只要願意學,什麼技巧不能學會?),而在於勇氣和決心。重複是敵人,而且是大塊頭的敵人,它就這般隨意地站著,勾起小指頭,傲慢地挑釁著你。而你,卻未必有戰風車的勇氣。是明知必敗嗎?還是不可戰勝?未戰先怯,這場戰爭你已經敗了。我見到的諸多遺留系統,重複代碼都是這樣開始蔓延的。——時間,見鬼的時間,其實大多數時候它都是你舉白旗時找來貼臉的遮羞布。

我常常說程序員要懶,例如要把重複的過程變成自動化,例如不要重複製造輪子,例如竭力少寫代碼完成更多的事。可惜,我們多數時候把這種懶,用錯了地方。懶於打掃,懶於行動,卻又不計後果的吃,代碼的體格怎麼能夠減得下來?就看著代碼的體格一天天膨脹下去,然後嗚呼哀哉吧。


推薦閱讀:

同樣都是銅線介質,為什麼 USB3就比2速度快了那麼多?
輸入URL以後和編碼
莫扎特的《魔笛》是否像有些人講的那樣——泄漏了共濟會的秘密?
為什麼在莫爾斯碼中不採取和布萊葉盲文一樣的換擋碼錶示切換英文和數字?

TAG:编码 |