代碼和設計是如何一步步腐化的

經歷了幾個從商業角度來看或成功或失敗的項目,都會發現代碼、設計都會慢慢地、在不經意間腐化。並且有一個項目開始的時候,架構是通過精心設計的,也有較爲嚴格的代碼規範,而且經過靜態代碼檢查來儘可能保證代碼的質量,連code review都有一個可供參考的checklist。但半年一年以後,仍是會發現,不少代碼都已經臃腫走樣,處處都是複製粘貼,動輒好幾千行代碼的模塊,能 work、但不 right的代碼。html

getting it work is easy
getting it right is hard程序員

不由想問問代碼和設計是如何一步步腐化的?設計模式

本文地址:http://www.javashuo.com/article/p-cmywjpng-cd.html架構

代碼如何開始腐爛

其實你們都據說過 clean code,但不必定真正意識到其重要性,且知道並不等同於作到,而時間更是一把殺豬刀,讓程序員禿了,讓代碼爛了。函數

一個新項目開始的時候,你們都是滿懷壯志,期待靈活可複用的架構,期待成功的產品。與此同時,敏捷開發告訴咱們不要過分設計,固然,自己也是很難預料到之後需求變化的方向,因而應該等到第一次變化的時候纔去考慮如何重構以應對這一類型的變化。但問題極可能就會出如今這裏。單元測試

也就是說,也許哪一天,當咱們須要加一個新功能的時候,會發現原來的設計和代碼不是很方便增長這個新功能。固然,咱們不該該過多苛責以前的設計,由於之前沒有預料到這個新功能,也就沒有在這個地方引入抽象。這個時候有兩種解決辦法:第一種是重構術,就是加功能以前先了解、重構已有的代碼,好比調整一下類的基礎體系、抽象出基類、或者引入一個間接層以隔離變化。另外一種則是修補術,在現有的函數中加一個 if-else(或者 switch case)、在現有的類中加幾個特殊字段。這兩種方法都能解決問題,修補術治標,重構術治本,但顯然,治標來得更快,治本對程序員的要求更高。測試

何時程序員會選擇修補術而不是重構術呢?ui

也許這個程序員看過 clean code、refactor,精通設計模式和麪向對象,也很是但願維護一份漂亮的代碼。但咱們知道,重構是須要時間的,並且還可能引入bug。也許重構耗費的時間就超過了用修補術 workaround 的時間,就短時間來講,修補術的性價比是更高的。那麼長遠來講呢,也許重構術的性價比更高?但是隻顧眼前、及時行樂是人的本能,走捷徑、偷懶是無時不存在的誘惑。固然,也許有追求的程序員會抵制這種誘惑,可是社會心理學告訴咱們,在壓力、干擾面前咱們很難理智思考,自控力也會失效。時間、進度壓力就是垂懸在程序員頭上的達摩克利斯之劍,這壓力可能讓人失眠、讓人頭禿,寫點垃圾代碼彷佛也無可厚非。設計

何況,重構還可能引入bug,重構的前提是要有完備的測試機制,單元測試、功能測試、集成測試一個都不能少。但是,理想很豐滿,現實很骨感,單元測試覆蓋率每每不足,並且還可能依靠手動迴歸測試。把代碼重構好了可能壓根沒人知道,沒人來感謝你、給你點個贊,但萬一重構出了bug呢,你們都會收到事故報告,說不定還會影響KPI?不求有功但求無過,Leader、經理是否定可重構的價值,也很大程度影響組員對於重構的積極性。代碼規範

固然,增長新功能的也許是一個新手,新手加入團隊後,通常就是從維護某個模塊,實現一些小需求入手。新手有可能水平自己就不行,並且業務邏輯和代碼都是陌生的,若是缺少完善的文檔以及足夠的掌握,新手是萬萬不敢重構的,修補術是最天然的選擇,複製、粘貼、稍微修改一下、build、run,成功啦!又實現了一個需求!你知道,新人是急於證實本身的,快速的實現一個又一個需求是證實本身的最佳辦法。

你有可能說,新人不是應該有個導師嗎,導師得review新人的代碼啊。首先,導師得懂這一塊業務;其次,導師得願意花時間指導新人。指導新人是否影響導師的KPI呢?帶好了是否有獎,出問題了是否有懲?若是全憑導師自律,這個不肯定性就太大了。

上面提到的是新人,其實老手也可能寫出「德不配位」的代碼,好比一個需求,可能涉及到多個模塊,有的模塊是這個老手負責的,有的則不是。理想的狀況下,各個模塊提供好接口供老手調用便可,但某個模塊的負責人很忙,沒有時間,這個時候老手就會直接去修改相應模塊。但是,可能因爲老手特有的自尊、或者面子,老手每每不肯意去請教對應模塊的負責人,而是按照本身的經驗魔改出一段能夠工做,但既不優雅、也不高效的代碼。

代碼如何加速腐爛

因此說,因爲進度壓力、經驗、態度等各類各樣的緣由,代碼中慢慢就會開始出現腐朽的問題。可怕的是,垃圾的代碼給出了錯誤的示範,這種示範對於新手或者對於這個模塊不熟悉的同事來講都很強烈,也使得垃圾的代碼、倍增的維護成本、潛在的bug被處處複製,美其名曰「借鑑」。破窗效應,讓後來人寫出垃圾代碼的時候毫無意理負擔,「之前就是這個樣子的」,之前這裏有個變量叫temp,我只是加了個變量叫temp1;之前這裏就有switch case,我只不過加了一個case;之前的代碼就很難讀懂了,因而我copy的一份實現本身的邏輯。

何況,到項目後期,可能再也不那麼掙錢了,可能最初寫代碼、制定規範的人已經再也不了,誰還會來關心這代碼質量呢?

悲觀的認爲,代碼的腐化是必要,只是時間快慢問題。

相關文章
相關標籤/搜索