面對祖傳屎山代碼應該采用的5個正確姿勢
1. 這世界上全是祖傳代碼
有的代碼傳了四五年,有的傳了十幾年,還有的傳了二十多年!
做Java的同學,你能想象得到只用JSP做的系統嗎? 我遇到過, 6000多行的JSP充當Controller, 有個程序員某一次在JSP中加代碼太多了,直接導致無法編譯了。
大名鼎鼎的Oracle很強吧?
2018年有個Oracle程序員吐槽說每次處理一個Bug ,都需要花費兩周時間搞清楚20個不同的flag以及它們之間的神秘作用,然后自己才能添加若干新flag和邏輯來fix bug。
然后需要將代碼提交到200台服務器組成的測試集群,等待20到30小時運行數百萬個測試。 可能有100~1000個測試失敗,你需要分析它們和更多的flag。
如此循環兩周,直到確保神秘的flag組合通過所有測試。
然后為你的更改再添加上百個測試,保證別人不會破壞。
是不是很瘋狂?
你也可以看看你手頭的代碼,看看最早的作者是誰,經歷了多少個版本。
我看到的最早的版本是1998年,那個作者現在是個高級的架構師了。
如果你很幸運, 一開始就啟動了一個全新的項目,沒有祖傳代碼的問題。
但是,請放心,根據“代碼腐化定律”和“破窗效應”, 你的項目很快就會變成“祖傳代碼”, 毫不例外!
2. 遏制你重寫代碼的沖動
我不止一次一邊砸鍵盤一邊罵: 這么爛的代碼,維護成本這么高,重寫得了!
但是理智告訴我: 重寫的成本更高,祖傳代碼雖然很爛,但是經歷過無數測試和真實用戶的考驗, 那些看起來無法理喻的分支、條件恰恰是在彌補那些程序員沒有考慮到的邏輯。
如果真的重寫,你能保證這些邊邊角角的邏輯都實現正確嗎? 能保證不出重大的紕漏嗎?能保證不給公司帶來重大的財務損失嗎?
軟件質量包括兩個方面: 內在的和外在的。
內在的是代碼質量, 外在的是對外表現的行為是否符合預期,不符合就是Bug了。
祖傳代碼的外在質量是不錯的,畢竟是經過血與火的考驗的。
如果重寫,你能保證內在的代碼質量和外在的行為都超越祖傳代碼嗎?
重寫不能保證業務中斷,這是基本條件, 2010年在華為做敏捷咨詢,華為有個口號我記得非常清楚: 要在高速公路上給汽車換輪子,這可能嗎? 據說華為有團隊真的做成了,如果是真的,確實讓人佩服。
3. 尋找優秀架構的影子
祖傳代碼雖然亂,但是初始的架構一般還是優秀的。
我在華為就看到有個產品是這樣的,應用層堆積起來的代碼看起來很差勁,但是仔細瞧瞧,依稀可見優秀架構的影子,這肯定沒有守住, 后來慢慢腐化了。
所以面對祖傳屎山代碼,要捏着鼻子,拋棄細節,在里邊努力搜索優秀架構的影子。
從功能上看,系統分為哪些組件,組件之間是如何交互的?
從技術上看,這些組件部署到了什么樣的軟件上? 組件之間交互用了哪些協議,同步還是異步?數據再組件之間如何流動?
一些核心組件的內部是如果進行再次划分的,如何分層的?
總之,要回答這么一個問題: 如果是我,我能獨自把這個系統給搭建起來嗎?
總有一天,你會成為這樣的人, 要做好儲備。
4. 在自己的范圍內盡量重構
面對祖傳代碼,初心不改。
努力把自己的代碼寫好,能重構的地方盡量重構,哪怕是一個函數,一個變量名。
這些都是自己賴以生存的技能,不能因為祖傳代碼爛,自己寫的代碼更爛!
重構和測試不分家, 把自己的單元測試寫好,把功能測試做好,必要的話請測試人員幫個忙。
一定要有勇氣去做,尤其是面對屎山代碼的時候。
要對得起自己,不能坑了自己。
5. 看優秀源碼
祖傳代碼雖然有優秀架構的影子, 但是看多了也會吐的。
在這個世界上還是有優秀源代碼的, 尤其是開源的代碼, 它們沒有進度的巨大壓力,維護者有足夠的時間打磨自己的代碼, 像一個工匠一樣。
我知道的一些優秀源碼有這些: JUnit,Redis,SQLite, Spring等。
這寫代碼現在都很龐雜了,看起來很累,最好去找他早期的源碼,要簡單得多,並且基本架構還在。
比如JUnit早期代碼,幾百行的代碼就把很多設計模式都給組合了起來,非常巧妙,設計模式看多少都不如看一個活生生的例子。
看完以后,自己嘗試着造一個輪子,把主要思想都給體現出來,你的功力至少上一個層次。