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早期程式碼,幾百行的程式碼就把很多設計模式都給組合了起來,非常巧妙,設計模式看多少都不如看一個活生生的例子。
看完以後,自己嘗試著造一個輪子,把主要思想都給體現出來,你的功力至少上一個層次。