簡評:一個系統的迭代開發可以持續幾年甚至更久,而某行代碼的生命周期則短很多,一次到位的開發不現實也沒有必要。代碼的正確性、安全性比美觀更重要,不要將時間浪費到編寫完美代碼上。
不同代碼重要性的優先級不同
Michael Feathers 在研究代碼隨時間發生的變化中,發現了代碼的生命線。
通常,每個系統都有許多一次寫成就幾乎不再修改的代碼。但是依然有一小部分代碼,包括最重要最有用的代碼,會被經常修改,重構甚至重寫數次。
隨著開發者對一個系統、一類問題或者一個架構方案的深入了解,應該能夠更加輕易地知道或者預測到哪些代碼會不停改動,哪些代碼幾乎永遠不變。換句話說,有的代碼比其他代碼更重要。
是否應該努力去寫完美代碼?
從第一個 hello world 開始,我們就知道應該努力寫簡潔的代碼,保持代碼的一致性和易讀性。于是一些強迫癥患者的程序員便開始癡迷于優雅完美的代碼,每時每刻都在斟酌重構代碼的每一個細節。
有的代碼只需要寫一次,以后就再也不需要作任何變動,但有些代碼并非如此。試想,這些需要不斷改變的代碼,代碼寫得那么完美卻在下一秒立馬就被 delete 豈不是太過浪費?而且也沒有必要這么做。
You Can't Write Perfect Software. Did that hurt? It shouldn't. Accept it as an axiom of life. Embrace it. Celebrate it. Because perfect software doesn't exist. No one in the brief history of computing has ever written a piece of perfect software. It's unlikely that you'll be the first. And unless you accept this as a fact, you'll end up wasting time and energy chasing an impossible dream.” — Andrew Hunt, The Pragmatic Programmer: from Journeyman to Master
只寫一次的代碼首要并非美觀或優雅,而是正確性和易讀性。因為在整個系統的生命周期中,它們雖然不再修改,但是可能需要被閱讀很多次。不一定非要緊湊,干凈即可。
在這些代碼中,一定程度上的拷貝和粘貼等操作也是可以接受的。它們不需要反復斟酌,除非你需要修改它,否則即使周圍代碼都在變,也不需要對這些代碼重構。對于這些代碼,沒必要花費過多時間。
至于那些頻繁修改的代碼,苦苦思索最優雅的方案更是在浪費時間,本來它們就可能在幾天后被修改或重寫。同樣,每次修改都癡迷于代碼的重構,或者重構那些不需要修改的代碼試圖使其變得更好也是沒有必要的。
代碼永遠都可以變得更好,但這永遠不是最重要的方面。我們關注的重點應該是 —— 這些代碼是否實現了所需功能?能否正確高效地運行?能否處理異常數據而不崩潰?即使異常,調試時是否方便?所有這些和美觀優雅無關的地方,才更應該是代碼質量優劣的衡量標準。
務實地進行編碼和重構
精益開發的核心思想是:不要把時間浪費到不重要的事情上。應該用這個原則指導我們如何編寫代碼,如何重構代碼,如何進行代碼審查以及如何進行代碼測試。
為了完成工作,只進行必要的代碼重構,Martin Fowler 稱之為機會主義重構和有預備的重構。這足以使代碼修改起來更加簡單和安全。如果你不是在修改代碼,代碼看起來是什么樣其實無關緊要。
在代碼審查中只關注真正重要的部分,這些代碼是否正確?是否是防御性的代碼?是否安全?你能否理解它的思路?修改起來是否安全?
不要糾結于代碼的風格(除非代碼風格誤導了你對代碼的理解),把格式化代碼的工作交給 IDE。沒有必要去爭論這些代碼能否“更加面向對象”。只要它有道理,至于是使用這用模式還是別的模式,并不重要。同樣,至于你是否喜歡,也不重要,盡管你可以用更好的方式完成它,除非你是在教對平臺或者語言不熟悉的新手,需要在代碼審查中完成監督工作。
測試用例的編寫很重要,需要覆蓋到主要的執行路徑和重要的異常情況。測試用例能夠用最少的工作量給你盡可能多的信息和信心,具體是采用大而全的測試還是小而精的測試則無關緊要。至于是在寫代碼之前寫測試用例還是在寫代碼之后寫測試用例也不重要,只要測試用例有效即可。
不僅僅是關于代碼
在軟件領域里,建筑師和工程師的概念從來都不適用,我們不是設計建造屹立數年或者數百年大橋或者摩天大樓,我們構建的是更加具有可塑性的、更加抽象的,同時生命周期也更加短暫的東西。軟件之所以稱為“軟件”,就是因為編寫代碼是為了修改。
After five years of use and modification, the source for a successful software program is often completely unrecognizable from its original form, while a successful building after five years is virtually untouched.— Kevin Tate, Sustainable Software Development
迭代開發教會我們不斷嘗試并檢查嘗試的結果 —— 是否解決了問題,如果沒有解決問題,如何去改進?
我們正在構建的軟件是永遠做不完的。盡管設計和編碼是正確的,那也可能只是一時正確,一旦需求發生變化,就會被更加適合的設計和編碼替代。
我們需要寫好的代碼:易懂,能夠正確運行,有安全保障的代碼。我們需要對它進行重構和代碼審查,并且編寫有效的測試用例。但是要記住,其中的一些代碼或者全部代碼可能很快就被丟掉,甚至再也不會被用到。我們需要意識到,我們的一部分工作可能要被浪費掉并且對此進行優化。
只做哪些需要被完成的事情,不要浪費時間試圖去編寫完美代碼。
原文鏈接:Don't Waste Time Writing Perfect Code
“本譯文僅供個人研習之用,謝絕任何轉載及用于任何商業用途。本譯文所涉法律后果均由本人承擔。本人同意簡書平臺在接獲有關著作權人的通知后,刪除文章。”
推薦閱讀:
Github | 程序員七大生產力工具
程序員常犯的五個非技術性錯誤