程式碼腐爛可以避免嗎?

文章首發於公眾號「陳樹義」及個人部落格 shuyi.tech,歡迎關注訪問。

一個蘋果放在桌子上不理它,它會慢慢地變壞。程式碼也跟蘋果一樣,會發生程式碼腐爛。壞的程式碼就跟壞的蘋果一樣,會更容易發生腐爛、腐爛得更快。工作時間久了,關注的角度從個人變成了團隊整體。我就會想:程式碼腐爛是否真的不可避免?有什麼辦法能夠避免程式碼腐爛呢?

程式碼腐爛可以避免嗎?

對於這個問題,我想了挺久,後面發現答案是:程式碼腐爛不可避免,只不過是時間問題。 雖然很沮喪,但是卻認清了事物的本質,走上了一條正確的道路。這比起不願意接受,然後制定錯誤的決定來得更好。

我給出程式碼腐爛不可避免的結論,其實是在思考了許多之後才做出的結論。程式碼品質高低取決於許多因素,包括但不限於:需求緊急程度、需求變化程度、團隊成員技術能力、團隊幸福感等等。這些因素都會從不同方面影響到程式碼品質,從而造成程式碼持續腐爛。

如果一個需求特別緊急,這時候我們不會考慮使用多麼高深的程式碼結構去實現,肯定是短平快直接開干。畢竟對於現在來說,時間才是我們真正的敵人。這時候的程式碼品質肯定沒有那麼高,考慮得也沒有那麼全面,這時候程式碼腐爛的進度條又快速往前跑了一步。

需求變化程度也會影響程式碼腐爛的程度。如果需求來來回回變化特別大,那麼我們很難設計一個統一的架構去適應需求。這時候就會出現分叉,分叉變得多了,程式碼結構就不好理解了。程式碼腐爛就自然而然發生了。

團隊成員技術能力也是一個很重要的點。很多時候我們希望大家能用更好的程式碼結構,例如設計模式,例如用封裝的思路來寫程式碼。但是團隊成員的能力是有區別的,有些人對程式碼能力強一點,對程式碼有追求,會做得很好。但是有些人能力就是差一些,很難寫出這麼好的程式碼。

簡單地說,希望通過某些流程規範去完全避免程式碼腐爛,那是不可能的。注意,我這裡說的是「完全避免」是不可能的。無論你做得多好,你的系統可能兩三年後就需要做一次重構,這太正常了。但我們可以通過一些流程規範,去減緩這種程式碼腐爛的發生。

弄清楚我們的目標是完全消滅程式碼腐爛,還是減緩程式碼腐爛,這非常重要。只有制定了正確的目標,我們才不會做出錯誤的決策,我們制定具體行動的時候才會更有信心。

文章首發於公眾號「陳樹義」及個人部落格 shuyi.tech,歡迎關注訪問。

如何減緩程式碼腐爛?

減緩程式碼腐爛,其實有好多種辦法。但最常見、收益最高、最好落地的兩個措施,我認為是:技術方案評審、CodeReview。

編寫技術方案,簡單地說就是在你開發之前先想好技術方案。整個需求是怎麼樣的,你想如何去實現這個需求?表結構你要怎麼調整?數據流從前到後的流動是怎樣的?你要做哪一些改動?而技術方案評審,則是拉上熟悉這塊業務的同學,讓他們一起看看你的技術方案。看看這種實現方案是否有問題,是否有更好的實現方式?

通過技術方案評審,我們基本上可以避免出現大的需求問題,並且能確保需求改動能符合原有的系統設計。即使不得已選擇了另外一個方式,出現了設計分叉,那大家也都知道這個事情的背景,更有利於後續解決問題。

CodeReview 則是對於技術方案的最終核對。很多時候技術方案寫的是 A,但是程式碼寫著寫著就變成了 B。CodeReview 的出現就可以避免這個問題。當然 CodeReview 還有很多其他好處,例如:提高程式碼品質等等。

總結

程式碼腐爛是不可避免的,幾乎所有系統都在發生不同程度的程式碼腐爛,大多數系統在兩三年後就要做一次重構。我們能做的只是減緩程式碼腐爛的速度,讓系統能夠撐得更久。而減緩程式碼腐爛的方法,技術方案評審和 CodeReview 是最基本的、最好用的兩個方法。

在周志明最新的書籍《鳳凰架構:構建可靠的大型分散式系統》里,他也說到:

架構腐化與生物的衰老過程很像,原因都來自於隨時間發生的微妙變化,如果你曾經參與過多個項目或產品的研發,應該能對以下場景有所共鳴:在項目開始的時候,團隊會花很多時間去決策該選擇什麼技術體系、哪種架構、怎樣的平台框架,甚至具體到開發、測試和持續集成工具。此時就像小孩子在選擇自己鍾愛的玩具,筆者相信無論決策的結果如何,團隊都會欣然選擇他們所想選擇的,並且堅信他們的選擇是正確的。

老人的退出、新人的加入使得團隊總是需要理解舊程式碼同時完成新功能的成員,技術專家偶爾來評審一下或救一救火,充其量只能算臨時抱佛腳;另一方面是程式碼會逐漸失控,時間長了一定會有某些並不適合放進最初設計中的需求出現,工期緊、任務重、業務複雜、程式碼不熟悉等都會成為欠下一筆技術債的妥協理由,原則底線每一次被細微地突破,都可能被破窗效應撕裂放大成觸目驚心的血痕,最終累積到每個新人到來就馬上能嗅出老朽腐臭味道的程度。

架構腐化與生物體衰老一樣,是不可避免的。老人退出、信任加入、工期緊、任務重等等原因,都是不斷欠下的技術債,我們無法避免。而對於程式碼腐爛,演進式設計或許是一個可解決的方案。簡單地說:演進式設計是不追求完美,而是追求滿足一定「保質期」內的合適,讓合適的架構在合理的生命周期中發揮價值。

演進式設計是ThoughtWorks提出的架構方法,無論是代際的演進還是漸進的演進,都帶有不少爭議,它不僅是建造的學問,也是破壞的學問。Neal Ford在Building EvolutionaryArchitectures:Support Constant Change一書中比較詳細地闡述了演進式架構的思想,獲得不少關注,卻不見得其中所有觀點都能得到廣泛認可。如果你是管理者,大概很難接受正是那些正常工作的系統帶來了研發效率的下降的觀點;如果你是程式設計師,估計不一定能接受程式碼復用性越高、可用性越低這樣與之前認知相悖的結論。

當我們思考清楚程式碼腐爛這件事情之後,或許我們就能更客觀、更平和地接受系統里那些爛程式碼。因為我們知道程式碼腐爛是一個自然法則,是不可避免的一件事情。我們能做的是盡量減緩腐爛的速度,讓系統在合理的生命周期里發揮它的價值。

文章首發於公眾號「陳樹義」及個人部落格 shuyi.tech,歡迎關注訪問。


我是樹義,用最簡單的語言,讓複雜的技術不再難懂。我們下次見!

如果文章對你有幫助,歡迎評論轉發點贊三連!