談一談我在軟件開發(fā)中的最佳實(shí)踐
“描述一個(gè)事物,唯有一個(gè)名詞定義它的概念,唯有一個(gè)動(dòng)詞揭露它的行為,唯有一個(gè)形容詞表現(xiàn)它的特征。要做的,就是用心去尋找那個(gè)名詞、那個(gè)動(dòng)詞、那個(gè)形容詞……”
——?福樓拜 (Gustave Flaubert)
我想講個(gè)故事。
很久很久以前(一般講故事都是這樣開頭吧), 兩個(gè)老工程師在一起聊天,談各自生涯中最自豪的工程。其中一個(gè)先講述了他的杰作:
“?我們建造的橋,橫跨一個(gè)峽谷,峽谷很寬很深。我們花了兩年時(shí)間研究地質(zhì),選擇材料。聘請(qǐng)了最好的工程師團(tuán)隊(duì)來設(shè)計(jì)方案,而這又花了五年時(shí)間。?我們簽下了最大的工程隊(duì),委托他們建造基礎(chǔ)結(jié)構(gòu)、塔墩、收費(fèi)亭,以及用于連接橋梁和高速公路的道路。橋面下層是鐵路,我們甚至還修了自行車道。?那座橋花費(fèi)了我數(shù)年的心血。”
另外一個(gè)聽完之后,陷入了沉思,過了一會(huì)兒,說到:
“?有一天晚上,我和一個(gè)朋友喝了點(diǎn)伏特加,然后我倆扔了一根繩子,越過一個(gè)河谷。呃…… 就是一根繩子,兩頭系在兩顆樹上。?河谷兩邊各有一個(gè)村莊,起初,有人加了個(gè)滑輪,用來傳遞包裹。然后,有人拉起了第二根繩子,勉強(qiáng)可以走走,雖然很危險(xiǎn),但小伙子們很喜歡。?后來,一群人重新修建了一下,使得更牢固。于是,女人們也開始從上面走,每天帶著她們的農(nóng)產(chǎn)品過橋。?就這樣,在橋的另一邊形成了一個(gè)市場。因?yàn)榈胤介_闊,造了很多房子,慢慢地發(fā)展成了一個(gè)鎮(zhèn)子。?繩索橋被木橋替代,這樣就可以走馬車了。?后來,鎮(zhèn)上的人們修了一座真正的石橋。再然后,人們又把石料改成了鋼材。?如今,那座鋼構(gòu)懸索橋依然佇立在那里。”
前一個(gè)工程師沉默良久,說到:“ 有意思。我那座橋建成大約十年后,被拆除了。事實(shí)證明我們選錯(cuò)了地點(diǎn),建好的橋沒人用。據(jù)說有幾個(gè)野路子的家伙,在下游幾英里處,拉了一根繩子,所有人都從那走?!?/p>
金門大橋(舊金山)
我很喜歡這個(gè)故事。故事的出處,在一款消息隊(duì)列產(chǎn)品——?ZeroMQ?的官方指南第6章里。
說完故事,我想聊聊軟件開發(fā)中,常??梢月牭降囊粋€(gè)概念 ——?Best Practice?:最佳實(shí)踐。Wikipedia 上對(duì)其解釋為:
A best practice is a method or technique that has been generally accepted as superior to any alternatives because it produces results that are superior to those achieved by other means or because it has become a standard way of doing things.
(最佳實(shí)踐是一種:因其產(chǎn)生的結(jié)果優(yōu)于其它選擇下的結(jié)果,或其已經(jīng)成為一種做事的標(biāo)準(zhǔn),從而被普遍認(rèn)可優(yōu)于任何替代方案的方法或技術(shù)。)
這個(gè)概念源于管理學(xué),然后在 IT 界泛濫。簡而言之,就是所謂“正確的做法”。
最佳實(shí)踐本身是美好的存在,猶如夜空中的一輪明月,照亮黑暗中的方向,指引著摸索前行的凡人。
但凡事有度,子曰:“過猶不及?!?/p>
我今天想說的,就是這月亮的背面。(傳說中,月球背面隱藏著…… 噓~)
潮汐鎖定導(dǎo)致月球永遠(yuǎn)以同一面朝向地球
首先,最佳實(shí)踐容易帶來思想包袱,讓人無法專注于解決問題本身。
總是希望采用最好的技術(shù)方法,不愿意在不正確的做法上浪費(fèi)時(shí)間,導(dǎo)致瞻前顧后,甚至裹足不前。此時(shí)的最佳實(shí)踐,已然成為了一種毒藥,一旦偏離了問題本身這個(gè)出發(fā)點(diǎn),就會(huì)不知不覺走進(jìn)“宏大構(gòu)想”的思維陷阱。把簡單的問題復(fù)雜化,阻礙了邁出第一步,直到能規(guī)劃出“包羅萬象”的解決方案后才肯動(dòng)手,拖延癥就這樣來了,時(shí)間卻走了。
你想好了未來每一天怎么過嗎…… 沒想好? 那……不活了?
其次,對(duì)最佳實(shí)踐的執(zhí)念容易讓人鉆牛角尖,將目標(biāo)的重心帶偏。
過度關(guān)注實(shí)施過程是否符合標(biāo)準(zhǔn)化,忽視了項(xiàng)目中其它重要的東西,比如用戶體驗(yàn),比如實(shí)際需求。就像故事里講的那樣:第一座大橋,幾乎是教科書般的標(biāo)準(zhǔn)化路數(shù),可產(chǎn)品落地后和客戶需求卻差了好幾英里;第二個(gè)看上去很野路子,但精準(zhǔn)地解決了痛點(diǎn),從始自終都是緊緊圍繞實(shí)際需求迭代,每一次的進(jìn)步都可以產(chǎn)生效用,這才叫殺手級(jí)應(yīng)用。
這讓我想起了?Plan-9?的傳說。
你聽說過 Plan-9 OS 嗎? 一款由貝爾實(shí)驗(yàn)室的極客們打造的用于完善 UNIX 不足的操作系統(tǒng)。什么不足?在 UNIX 的哲學(xué)中,有一條叫做 “一切皆文件” ,但實(shí)際上UNIX本身并沒有嚴(yán)格遵從這一條。于是,Plan-9 OS 完美實(shí)現(xiàn)了這一點(diǎn)。然后呢……? 沒有然后了。它從沒進(jìn)過市場,所以如果你沒聽說過它,一點(diǎn)也不奇怪。Plan-9 OS 沒有解決任何現(xiàn)實(shí)問題,沒人在乎 “一切皆不皆文件”。
這種執(zhí)念的另一種表現(xiàn)就是工程師思維,沉迷于奇技淫巧中無法自拔,程序員尤其容易中招。
比如性能優(yōu)化?!皟?yōu)秀的程序員應(yīng)該榨干每一字節(jié)內(nèi)存”,聽起來很熟悉,不是嗎?但經(jīng)濟(jì)學(xué)上來講,邊際效應(yīng)決定了一次項(xiàng)目中,越優(yōu)化性價(jià)比越低。有一個(gè)很容易被忽略的事實(shí):硬件其實(shí)比程序員要便宜。
再比如對(duì)設(shè)計(jì)模式的崇拜。設(shè)計(jì)模式當(dāng)然是好東西,但如果像強(qiáng)迫癥一樣使用它們,堅(jiān)持用上它們才是正確的編程,就會(huì)導(dǎo)致按圖索驥,強(qiáng)行讓問題去適應(yīng)設(shè)計(jì)模式,而不是讓解決方案針對(duì)問題,這就本末倒置了。
我有個(gè)基友,C++ 極客。畢業(yè)后入了騰訊,積累了巨額財(cái)富后,自己創(chuàng)業(yè)了。當(dāng)然,當(dāng)老板可比寫 C++ 難多了,于是現(xiàn)在又去積累巨額財(cái)富了。想當(dāng)年和那廝聊天,言必出設(shè)計(jì)模式,沒事侃正則,再?zèng)]事就研究 GC 策略 (好像玩 C++ 的普遍這德性) 。前不久看他代碼,差點(diǎn)沒認(rèn)出來,這家伙畫風(fēng)一轉(zhuǎn),現(xiàn)在連接口都懶得多用(估計(jì)看到這,某些狂熱分子肯定在破口大罵:你什么意思,你說你沒用面向接口編程?)那位兄臺(tái)甚至都懶得多聊,輕描淡寫來一句,“沒心思,以后有需要再加?!?/p>
順便扯一句,那哥們最近負(fù)責(zé)開發(fā)一款手游,他跟老板匯報(bào)的時(shí)候,預(yù)估的研發(fā)周期要12個(gè)月,然后老板跟他說:“好,12月出公測?!?(哈~ 估計(jì)他肯定舌頭打結(jié)把“12個(gè)月”說成了“12月”)??吹竭@的你,是否回憶起了你的老板?
這也是我接下來想說的關(guān)于最佳實(shí)踐的另一個(gè)問題:項(xiàng)目實(shí)施。
工作數(shù)年,大小項(xiàng)目經(jīng)歷若干,慢慢體會(huì)到,一個(gè)項(xiàng)目的開發(fā)順利與否,并不在于技術(shù)選型是否為最佳實(shí)踐,更多的時(shí)候,取決于開發(fā)方案和技術(shù)儲(chǔ)備之間的平衡。做項(xiàng)目畢竟是要講方案落地的,如果最佳實(shí)踐中的技術(shù)成本,超出了開發(fā)者的落實(shí)能力,那就是坑,這時(shí)盲從最佳實(shí)踐無異于挖墳。如果是一個(gè)人的項(xiàng)目,抽時(shí)間惡補(bǔ)一通,興許能填填坑,這取決于IQ。但要是一個(gè)團(tuán)隊(duì),那就不是什么 IQ,EQ,QQ 的問題了,這中間產(chǎn)生的學(xué)習(xí)成本,集體培訓(xùn)成本,反復(fù)溝通成本,大量的初級(jí)錯(cuò)誤,千奇百怪的代碼,互相沖突引發(fā)的焦躁情緒,等等。這些負(fù)面的東西如果不能妥善的處理,足以抵消掉最佳實(shí)踐帶來的好處。別忘了,deadline 正在迫近。
我自己曾經(jīng)在一個(gè)項(xiàng)目組里,強(qiáng)行推行?Git?做源代碼管理,當(dāng)時(shí)組里共9人,有7人只會(huì) SVN,但我堅(jiān)持 Git 是 “最佳實(shí)踐”。要不說年少無知少不更事呢,罷了,后來的事情我不想回憶了…… 那次項(xiàng)目之后,我再也不在一群只會(huì) SVN 的隊(duì)伍里提 Git 了。
一個(gè)人做軟件已經(jīng)很難,比這更難的,是一群人做軟件。
當(dāng)塵埃落定,驀然回首,最佳實(shí)踐很可能沒你想象中那么重要。它更多的是一種精神層面的求道,并非物質(zhì)世界的必要。
扎克伯格 ( Mark Zuckerberg ) 于2004年在哈佛柯克蘭公寓 ( Kirkland House ) 里寫出?TheFacebook?的時(shí)候 ( 次年更名為Facebook ) ,用的是 “世界上最好的編程語言” PHP。這門可能是業(yè)界被吐槽次數(shù)最多的語言一直支撐著FB帝國的誕生,直到席卷全球。Stack Overflow?的聯(lián)合創(chuàng)始人 Jeff Atwood 曾公開揶揄 Facebook 是一家 “召集全球頂級(jí)程序員在 Windows XP 上寫 PHP ” 的公司。但這無所謂,24年前的馬克也不糾結(jié)。一直等到需要的時(shí)候 (2010年),F(xiàn)acebook自己動(dòng)手研發(fā)了一個(gè)編程語言 —— Hack,來解決 PHP 帶來的危機(jī)。
《社交網(wǎng)絡(luò)》
最佳實(shí)踐,關(guān)鍵在時(shí)機(jī)(Timing)。
如果說用 Facebook 這個(gè) “根本不存在” 的網(wǎng)站來舉例,純屬虛構(gòu)的話,那我們來說點(diǎn)真實(shí)的例子,Web 技術(shù)的基石——HTML。由20世紀(jì)最重要的100人之一的?Tim Berners-Lee?創(chuàng)造的 HTML,其發(fā)明之偉大,足以單獨(dú)開篇博文來贊美了,這里就不贅述了。
這樣一個(gè)造福全人類的神作,本身的設(shè)計(jì)結(jié)構(gòu)絕非完美,甚至可以用混亂不堪來形容。沒有嚴(yán)格統(tǒng)一的約束,形同虛設(shè)的規(guī)范,標(biāo)準(zhǔn)化進(jìn)程的難產(chǎn)。以至于在很長一段時(shí)間內(nèi),連自身元素的定義,都可以向?yàn)g覽器廠商妥協(xié)。但是,種種被人詬病的存在,絲毫不影響 HTML 改變世界的腳步。你我今天能相會(huì)于園,皆仰賴它的誕生。
同樣的例子還發(fā)生在 Web 世界另一個(gè)巨擎上——JavaScript。當(dāng)今世界,Web 前端技術(shù)已經(jīng)水銀瀉地般肆虐整個(gè)開發(fā)界,前端框架百花齊放、JS 衍生品鱗次櫛比。所有這一切的背后,全都源于上世紀(jì)90年代橫空出世的 JavaScript。
那么,JavaScript是最佳實(shí)踐嗎?
別逗了,如果有什么語言可以和剛才說到的 PHP 競爭一下誰被罵的次數(shù)更多,那非 JavaScript 莫屬。這個(gè)僅花了十天設(shè)計(jì)出來的語言,打一出身就被貼上了怪胎的標(biāo)簽?;靵y的標(biāo)準(zhǔn),多樣的實(shí)現(xiàn),安全漏洞,語法隨意,反人類……?總之,JavaScript 和最佳實(shí)踐半毛錢關(guān)系都扯不上,但它卻是撐起當(dāng)今互聯(lián)網(wǎng)半壁江山的擎天柱。
所以,用最接地氣地話來說,不管黑貓白貓,逮著耗子就是最佳實(shí)踐貓。
彼之蜜糖,吾之砒霜。所謂最佳實(shí)踐,其定義本身往往也是分歧的源頭。什么是最佳?這個(gè)最佳是獨(dú)一無二的嗎?世界上有很多很多現(xiàn)實(shí)問題,可能根本就沒有所謂的最佳實(shí)踐。
請(qǐng)聽題,世界上最好的編程語言是哪個(gè)?
第二題,世界上最好的文本編輯器是哪個(gè)?
朋友,這天還聊得下去嗎……
最后,說一個(gè)我自己的故事。
很久很久以前,為了找一款滿意的文本編輯器,我干了一件可能是前無古人,后不知道有沒有來者的蠢事 —— 我打開 Wikipedia,搜索 “ text editor ” ,然后轉(zhuǎn)到一個(gè)叫做 “ List of text editors ” 的頁面,接下來的一個(gè)月,我?guī)缀醢旬?dāng)時(shí)那個(gè)頁面上,所有我能下載安裝的文本編輯器,全部試用了一遍……
嗯?你問我為什么這么做?呵呵,不把全世界的文本編輯器遍歷一遍,我怎么知道哪個(gè)是最好的?
這事細(xì)節(jié)我不想再提了,我也不想回憶了。要不說年少無知少不更事呢,時(shí)至今日,我想不出比這更愚蠢的事了。WTF~~
這個(gè)頁面上的表格行數(shù)逐年增多
如今,再有人問我最好的編程語言或者最好的文本編輯器的問題的話,我會(huì)說:
“朋友,要打架嗎?”
這兩個(gè)問題的最佳實(shí)踐,唯有暴力。