不要浪費時間寫完美代碼
一個系統可以維持5年,10年,甚至20年以上,但是代碼和設計模式的生命周期非常短,當對一個解決方案使用不同的方法進行迭代的時候,通常只能維持數月,數日,甚至幾分鐘的時間。
代碼重要性區分
隨著對代碼是如何改變的研究,致力于代碼修改藝術的人發現了一個代碼庫的規律曲線。每個系統都有很多從未改變的代碼。但是也有小部分非常重要且有用的代碼一次又一次的改變,經過了多次重構和重寫。
當你對一個系統,問題域,或者架構方法越來越熟悉的時候,就更容易發現和預測哪些代碼會經常修改,哪些代碼不會被修改,即區分重要代碼和非重要代碼。
我們應該嘗試追求完美代碼?
眾所周知,我們應該寫干凈整潔的代碼,而干凈整潔就應該是盡可能一致,易懂,簡單。
有些人追求極致,強迫自己寫的代碼要漂亮且優雅,接近于他們所能達到的完美,瘋狂的進行重構,并致力于每一個細節。
與寫完代碼不再變動相比,一直修改的代碼會讓完美的需求和具有前瞻性的設計變得有些多余和沒必要。
你不能寫出完美的軟件,這樣的結果會使你受傷了?沒必要,把它當做人生格言,信奉并祝賀,因為完美的軟件并不存在,在計算機歷史中沒一個人曾經寫出過完美軟件,當然,你也不可能成為第一個,只有接受這樣一個事實,你才能不再在浪費時間,將精力放在可能實現的理想中。
Andrew Hunt, 實用程序員:從路人到大師
曾經寫過的代碼不需要優美優雅。它必須是正確的且容易理解的,因為在系統的生命周期中那些從不用修改的代碼也會被多次訪問。同樣這些代碼不需要又整潔又緊湊——只要整潔就足夠了。在一定程度上, 復制粘貼 和其他快捷方法寫出的代碼是允許的。 即使這些代碼周圍的代碼變了, 這些代碼不需要反復修改,不需要重構(直到你需要修改它)。這樣的代碼是不值得花費額外的時間的。
那些經常修改的代碼該如何處理呢?苦思冥想代碼風格和提出最優雅的解決方案是浪費時間的,因為這些代碼可能會在幾天或幾周之內再次修改,甚至重寫。因為希望代碼應該變得更好而 癡迷地重構 那些需要經常修改代碼,或者重構那些基本不會修改的代碼。代碼一直可以變得更好,但這并不重要。
最重要的是:代碼是否做到了它應該做的事?代碼運行正確且可用又高效嗎?能夠 處理錯誤和錯誤數據 而不奔潰或者至少是 安全地出錯 嗎?容易調試嗎?能簡單又安全地修改代碼嗎?這些不是對于完美代碼的主觀想法,而是用來區分成功和失敗的切實可行的措施。
實用的編碼和重構
精益開發的核心思想是:不要浪費時間在那些不重要的事情上。這句話已告訴我們該怎樣寫代碼,怎樣重構代碼,怎樣評審代碼,怎樣測試代碼。
為了把工作做好, 只重構你需要的 —— Martin Fowler 稱為機會主義重構(理解、清理不切實際的東西)和預先重構。足夠讓修改變得更簡單更安全即可,其他的不必考慮。如果你不修改那些代碼,那么那些代碼長什么樣子是無所謂的事。
在代碼評審中, 只關注那些重要的 。代碼正確嗎?有防范機制嗎?安全嗎?容易理解嗎?能夠安全地修改嗎?
忘掉編碼風格(除非編碼風格達到可理解的程度)。讓你的 IDE 處理格式化。不要過多爭論:代碼是否可以是“更多的OO”。只要它有意義,不管它是否適當地遵循這種或那種模式,這些都不重要。無論你喜歡還是不喜歡都沒關系。無論你能否以更好的方式做到這一點并不重要——除非你在教一個對平臺和語言都不熟悉的新手,而且你需要做一些代碼評審作為指導的一部分。
寫測試是有必要的。測試那些涵蓋主路徑和重要例外情況的測試。測試可以讓你以最少的工作量獲得最多的自信心。 大規模全范圍測試或者小規模局部測試 ——在編寫代碼之前測試還是之后測試,都沒關系,只要做了這個工作就行。
這不(僅)是關于代碼
建筑學和工程學的隱喻從未在軟件開發中生效。我們不是設計和建造橋梁或摩天大樓 —— 它們會在幾年或幾代內保持基本相同。我們正在建造一些更富有創造力和抽象性、更加短暫的東西。代碼編寫之后是用來修改的 —— 這就是為什么它被稱為“軟件”的原因。
“經過五年的使用和修改,成功的軟件的源碼通常與最初版本完全不一樣,而五年之后的成功的建筑幾乎沒有什么變化。”
Kevin Tate, 可持續軟件開發
我們需要將代碼看作是我們工作的一個暫存:
…有時在面對更重要的事情時,我們被引導到盲目崇拜代碼。我們經常會處于這樣的幻象中:在移交產品時最有價值的東西是代碼,實際上這可能是對問題域的理解、設計難題的進展甚至是客戶反饋。
Dan Grover, 代碼和創造性破壞
迭代開發教會了我們通過實驗來驗證我們工作的結果 —— 我們是否已解決了這個問題,如果沒有,我們學到了什么,我們該如何改進?我們正在構建的軟件永遠不會完成。即使設計和代碼是正確的,它們可能也只是在一段時間內是正確的,直到環境要求其再次改動或被替換為更好的東西。
我們需要編寫好的代碼:可理解、正確、安全和可靠的代碼。我們需要重構和審查它,并寫出好的有用的測試用例,直到其中的一些代碼(也可能是全部(),可能會很快被拋棄,或者可能永遠不會被再次看到,或根本不會使用了。我們需要認識到,我們的一些工作必然會被浪費掉,并要為此進行優化。做那些必須做的,不做無用功。不要浪費時間嘗試編寫完美的代碼。