寫(xiě)碼容易,讀碼難:工程師,千萬(wàn)別重寫(xiě)程式碼
作為 100offer 工程師拍賣(mài)的行銷(xiāo),我們常常和用戶(hù)交流討論,有一個(gè)話(huà)題經(jīng)久不衰:工程師入職新公司後接手已有的程式碼,怎麼處理?
大家都有一顆工程師的心,所以當他們到一片新的場(chǎng)地想做的第一件事就是,將舊的一切打掉重來(lái)。是的,他們決不會(huì )滿(mǎn)足於簡(jiǎn)單的增加勞動(dòng)量。
或許這種微妙的心理定位可以解釋?zhuān)簽槭颤N工程師進(jìn)入新專(zhuān)案後寧願丟掉舊程式碼重新寫(xiě),也不願意修修補補,他們認為舊程式碼簡(jiǎn)直一團糟。
但是,事實(shí)上真是這樣嗎?你之所以認為舊程式碼一團糟,其實(shí)是由一個(gè)基本定律決定的,那就是:寫(xiě)碼容易,讀碼難。
為什麼你覺(jué)得舊程式碼異?;靵y?因為讀代碼更難
這大概就是程式碼 Reuse 難以實(shí)現的原因,也可以解釋為什麼你組裡的每個(gè)人都喜歡用不同的功能將分割的字元串轉換成一個(gè)數組。比起猜測舊的功能是怎樣實(shí)現的,重新寫(xiě)一個(gè)自己的功能要簡(jiǎn)單和有趣多了。
作為這個(gè)公理的推論,你可以問(wèn)問(wèn)身邊的工程師他們正在奮戰的程式碼怎麼樣?「簡(jiǎn)直是一塌糊塗!」他們肯定會(huì )這樣說(shuō)?!肝液?jiǎn)直想打掉重來(lái)!」
為什麼認為程式碼這麼糟糕呢?「看看這個(gè)功能,竟然有兩頁(yè)長(cháng)!完全不知道這些東西為什麼在這裡!完全不知道這些 API 是幹什麼的?!顾麄儠?huì )這樣回答你。
▲漫畫(huà):讀別人程式碼是一種怎樣的體驗?
曾經(jīng), Borland 的創(chuàng )辦人 Philippe Kahn 當初就是向記者們吹噓: Quattro Pro 會(huì )比 Microsoft Excel 要好用得多,因為它是從頭開(kāi)始編寫(xiě)的,全部都是新的源始碼!
但是,認為新程式碼比舊程式碼好簡(jiǎn)直就是荒謬。舊程式碼是已經(jīng)運行過(guò)的,測試過(guò)的。無(wú)數的 Bug 在被發(fā)現前都上線(xiàn)運行過(guò),發(fā)現之後工程師們可能在花了好些日子才修復了這些 bug 。這種修復可能是一行程式碼,也可能是幾個(gè)字元,無(wú)數的時(shí)間和精力都花在了這些 bug 修復上。
當你決定拋棄這些舊程式碼從零開(kāi)始的時(shí)候,你也丟掉全部前任努力的結果。
新程式碼一定比舊程式碼好? NO,重寫(xiě)可能會(huì )帶來(lái)更大的風(fēng)險
對技術(shù)領(lǐng)導者來(lái)說(shuō),重寫(xiě)專(zhuān)案的程式碼代碼也是一個(gè)異常艱難的決定。因為從公司層面說(shuō),重寫(xiě)程式碼甚至會(huì )威脅產(chǎn)品的市場(chǎng)競爭力。一旦決定重寫(xiě)程式碼,那麼與競品相比,你可能落後了 2~3 年——在軟體行業(yè),這時(shí)間可夠長(cháng)的。
▲你理想中的新程式碼會(huì )帶來(lái)產(chǎn)品功能的提升
但事實(shí)上,即便重寫(xiě)的新程式碼可以實(shí)現舊程式碼的所有功能和需求,但是為產(chǎn)品帶來(lái)的市場(chǎng)競爭力只有邊際提升。因為重寫(xiě)用的新技術(shù)、新語(yǔ)言、新框架並沒(méi)有給產(chǎn)品帶來(lái)質(zhì)的提昇。
更不用說(shuō)在重寫(xiě)的漫長(cháng)過(guò)程中可能會(huì )遇到一些意外情況,比如:
1、缺錢(qián):資金鍊的斷裂
2、缺人:核心工程師離職
最終導致效果不佳:達不到原產(chǎn)品應有的所有功能和需求,白白浪費了時(shí)間和金錢(qián),也丟掉了市場(chǎng)競爭力。
所以重寫(xiě)程式碼意味著(zhù),你在把自己置身於非常危險的境地,可能幾年後你也寫(xiě)不出比以前更好的代碼。你只是花了一大筆錢(qián)把已經(jīng)存在的程式碼又寫(xiě)了一遍。
當你覺(jué)得眼前的舊程式碼很爛時(shí),該怎麼辦?
你覺(jué)得舊程式碼寫(xiě)的很爛,那又怎樣呢?它們已經(jīng)上線(xiàn),已經(jīng)在實(shí)際運行中承受住了考驗。所以當你發(fā)現前任留下的程式碼亂七八糟的時(shí)候,不妨冷靜下來(lái),從以下三個(gè)方面入手理解程式碼、改善程式碼:
1、程式碼的結構有問(wèn)題
如果一段網(wǎng)路程式碼突然彈出了自己的對話(huà)框,應該是 UI 程式碼需要被處理。這些問(wèn)題可以被解決掉,你要一次次小心地移動(dòng)程式碼,重構,改變介面。還需要一位細心的工程師立馬仔細地檢查這些改變是否有問(wèn)題,從而不打擾到其他人。事實(shí)上,甚至比較大的結構變化也可以不扔掉代碼程式碼來(lái)完成。
大牛工程師 Joel Spolsky 回憶說(shuō),曾經(jīng)在某個(gè)專(zhuān)案中,他和他的團隊花了好幾個(gè)月重新架構在一點(diǎn)上:把程式碼動(dòng)來(lái)動(dòng)去、清理、創(chuàng )建有意義的基類(lèi),並創(chuàng )建了模塊之間的完美介面。但是他們始終非常小心翼翼,並沒(méi)有產(chǎn)生新的 bug ,也沒(méi)有丟掉任何舊程式碼。
2、程式碼的效率不高
曾經(jīng), Netscape 的渲染程式碼被傳非常緩慢。但事實(shí)上,這只會(huì )影響該專(zhuān)案的一小部分,這部分是你可以?xún)?yōu)化甚至重寫(xiě)的。你完全不必重寫(xiě)全部程式碼。優(yōu)化速度的 1% 工作量,會(huì )讓你獲得 99% 的爆炸性提升。
3、程式碼寫(xiě)得很醜
有些程式碼真的寫(xiě)的很醜,比如 Joel 曾參與一個(gè)專(zhuān)案,開(kāi)始用下劃線(xiàn)做開(kāi)始的成員變量協(xié)定,但後來(lái)改用更標準的「M_」。所以一半的功能用「_」開(kāi)始,一半用「M」開(kāi)始,這看起來(lái)真的很醜陋。但這個(gè)問(wèn)題 5 分鐘就能解決,而不用從頭開(kāi)始寫(xiě)全部的程式碼。
最後,你要記住,從頭開(kāi)始再寫(xiě)一遍並不意味著(zhù)你會(huì )寫(xiě)出比以前更好的程式碼。因為你沒(méi)有參與到上一個(gè)版本的建立,所以你其實(shí)根本就不算有經(jīng)驗。一旦你準備打掉重寫(xiě),你可能會(huì )再犯一遍版本一犯過(guò)的錯,甚至會(huì )產(chǎn)生更多的新問(wèn)題。
總結
面對糟糕的舊代程式碼 Keep Calm & Carry On!
在大型商業(yè)專(zhuān)案中,打掉重來(lái)是非常危險的行為。當然,如果你是在做實(shí)驗,想到新演演算法可以隨時(shí)重寫(xiě)。如果你跳槽、或剛接手一個(gè)新專(zhuān)案,面對看上去異?;靵y的舊程式碼,請冷靜下來(lái),忍住打掉重寫(xiě)的衝動(dòng),想想上面這些經(jīng)驗之談。