十年的老代碼,你敢動?
怎樣不讓猴子吃香蕉
你入職一家新單位,被告知需要維護一個老產品,經理找質管給你開通了svn權限,告訴你遷出哪個分支——就是那個十年前已經定型的分支,就是那個超過6代程序員維護過的分支——然后告訴你說,就在這個分支上改,添加一個新接口,以便支持H5 Video。
于是你開始看代碼,云山霧罩,各種痛苦,完全搞不懂業務邏輯和代碼的關系,也鬧不明白這塊代碼為什么這么寫那塊代碼是幾個意思。你戰戰兢兢如履薄冰思前想后寸步難行。
你去問進來5個多月還沒轉正的老同事,他告訴你他也不懂,讓你湊合著加個新接口實現了功能就行。加了新功能就行。
你去問干了快一年的資格更老的同事,他叮囑你千萬別動里面的代碼,千萬別管里面什么樣,就在外面包一層,先交付新功能,其它的有時間再說,里面的邏輯十年沒人動過了,沒有一個人能說清楚怎么回事,你要是改,一不留神就遍地狼煙。
你怎么辦?
怎樣不讓猴子吃香蕉
我想起來猴子吃香蕉的實驗:
鐵籠里關了五只猴,實驗者放進一掛鮮嫩甜美的香蕉,五猴頓時興奮起來,環視了周圍,其中一只率先伸手去抓。這時,實驗者以高壓水槍沖擊,包括那四只僅有念頭尚未行動的,也受到了懲罰。
過了會兒,看看沒有動靜,水果香氣四溢,又一只猴躍躍欲試竄到香蕉前,高壓水槍的集體懲罰再次啟動。如此這般幾個回合下來,猴都變得老實了,眼睜睜看著令之饞涎欲滴的果實,竟無一只敢再嘗試——因集體受罰的經驗令之膽寒。
此時,實驗者撤出一只水淋淋渾身發抖之猴,換進只新猴,這個不知天高地厚的家伙一進籠就奔 香蕉而去;這時,一種現像出現了:四只吃盡苦頭的猴一擁而上,撕扯、阻撓這冒失鬼,不讓它接近深具誘惑力的美味,以免大家跟著受罪。
至此,高壓水槍這專政手段暫且擱置,威懾效果依舊。等猴子一只只置換完畢,五只新猴面對香蕉皆不敢造次,個個循規蹈距,成就了“自律”的一群。
在這個籠里一個奇異的景象出現了:猴們最愛吃的香蕉,成了“禁果”!
——2006年第 3 期 《隨筆》朱家泰
關于老代碼的禁忌
對程序員來講,維護老代碼是最惡心的事兒之一。沒說的,就是惡心,公認的惡心,連我這種自認為隨意、靈活、代碼適應性強、沒有原則的老程序員也覺得維護老代碼是一種罪。如果你恨一個程序員,就讓他去維護年久失修搖搖欲墜的老代碼吧。
然而,本文開始時提到的情況卻幾乎是每一個程序員都會碰見的。老代碼啊,我們恨之厭之煩之遠之卻不可棄之。對一家軟件企業來講,老代碼就是資產,是多年積累下來的核心資產和重要競爭力。尤其是軟件產品,一份代碼先后幾波人維護過是常有的事。
這種時候,老代碼就老而成精有了生命,每當有新人進來,它都會用特有的超出我們耳力邊界的高頻發出聲音:警告,警告,一波新程序員正在趕來,快給它們點厲害殺殺它們的士氣。
而且,部分熟悉老代碼的老程序員也會諄諄告誡我們,這幾個文件不要動,這幾個類不要動,這里一改就奔潰,那里一改就連不上服務器,雷區標識很多。還有那一進來就因為被告誡而根本就沒看過老代碼的程序員也會告誡我們,那代碼誰也不懂,多少年沒人動過了,不動為妙,免惹麻煩……
故事就這樣發生了,禁忌就如此這般傳承下來。我們知道那里可能有問題,可是沒人敢去動它,等最后一個熟悉一部分老代碼的程序員悠然遠去,此地空余嘆息,從此以后,新來的程序員就成了想吃香蕉的猴子。
動,還是不動?
老代碼成了禁忌,我們往往被迫(沒時間或不愿意或害怕或不屑)在漂浮海面的冰山的尖尖上修修補補,深入了解深層代碼成了誰也不愿言說的痛。
然而都不懂看代碼都不動老代碼,老代碼只能越來越老越來越陳腐,越來越沒人敢動。越往后動的代價越高越沒人敢動。這對公司和團隊都不好。裹一層又一層,終將積重難返成為裹腳布,無人問津。
而一旦老代碼沒人能夠把握,這些作為資產的代碼實際上已經丟了,不再有價值增長了,原本領先的優勢隨著同行們百舸爭流的追趕漸漸失去了。
這是對企業是一種損失。讀程序員其實也是一種損失。
為什么這般講?
情人還是老的好
程序員有個毛病:自己不寫文檔卻老抱怨別人的代碼沒文檔,而碰見了有文檔的代碼卻又往往棄文檔如敝履。所以,業界流傳一句話:代碼即文檔。所以,業界的代碼和文檔,少見匹配的。
哇咔咔咔,對吧。
所以,我們只能接受這個現實:代碼即文檔。
所以,對維護老產品的程序員來講,要想弄明白老產品的邏輯,就只要如下兩個辦法:
- 找到熟悉產品的前輩,讓他給你講講。如果你找了產品經理,他只能告訴產品設計上如何如何。如果你找了程序員,他通常會說就是這樣那樣,然后說一句高深莫測又拉仇恨的話:看看代碼就明白了。
- 自己啃代碼,啃代碼,啃代碼。
Ok,維護舊產品,弄明白產品設計邏輯和代碼實現邏輯是非常重要的。
對于本文一開始提到的問題,其實也可能有在外圍包裝的辦法,比如你封裝一個本地的HTTP Server,用舊API拿到數據作為HTTP流轉發一下就能支持H5 Video標簽了。也可能很多情況都存在折衷的替代辦法。
然而,能弄懂代碼是如何實現產品和業務的,還是有非常重要的好處——對程序員來講很重要的好處:
文檔是會過時的,代碼是不會說謊的,讀懂代碼,你就真真正正明白了業務是如何實現的。對于沒人敢動而又核心的老代碼,你搞明白了,就占領了戰略要地。
這里我要引用格力空調的一句廣告詞:掌握核心科技。不管這是吹的還是怎的,話說得不錯,掌握核心科技才有競爭力,對程序員來講也是一樣,唯有掌握核心業務和代碼,才能彰顯自己的價值。
除此之外,讀代碼也是非常重要的學習途徑,尤其是經歷過線上考驗的代碼,必然尤其過人之處。在閱讀的過程中,我們可以學到很多東西,既可以學到業務,也可以學到設計。退一萬步講,即便你認為你水平遠超一般人屬于一針頂破天的那位,也還是可以從當時、當地的選擇中學到東西:見賢可以思齊,見過可以自省。
所以,我的主張是:老代碼,動啊,為什么不動!
不能拒絕時就接納,無需排斥,何時何地都可以修行,只要有心,處處都是成長的機會。最不濟,也鍛煉了閱讀代碼的能力,庖丁解牛之技成了,也可以在將來以無刃入有間,發揮用武之地。
至于怎么讀代碼改代碼,相信比學宋仲基撩妹容易多了,一句話:多讀讀就好了。當然展開來講也可以有很多技巧,我后面會有一篇文章來談。