不要浪費時間寫完美的程式碼

發表於2017-09-30

系統可以持續執行 5 年、10 年甚至 20 年或者更多年。但是,特定的程式碼行的生命,即使是經過設計,通常要短得多:當你通過各種方式來迭代尋求解決方案時,它會有幾個月、幾天甚至幾分鐘的生命。

一些程式碼比其他程式碼重要

通過研究程式碼如何隨時間變化,Michael Feathers 確定了一個程式碼庫的冥曲線。每個系統都有程式碼,通常有很多是一次性寫成,永遠都不會改變。但是有少量的程式碼,包括最重要和最有用的程式碼,會一次又一次地改變、會有幾次重構或者從頭重寫。

當你在一個系統、或者問題領域、體系結構方法中有更多經驗時,會更容易瞭解並預測什麼程式碼將一直改變,哪些程式碼將永遠不會改變:什麼程式碼重要,什麼程式碼不重要。

我們應該嘗試編寫完美的程式碼麼?

我們知道我們應該寫乾淨的程式碼,程式碼應該一致、清晰也要儘可能簡單。

有些人把這變成了極端,他們迫使自己寫出美麗、優雅、接近完美的程式碼,痴迷於重構並且糾結每個細節。

但是,如果程式碼只寫一次而從不改變,或者如果在另一個極端下,它一直在改變的話,就如同嘗試去寫完美的需求和嘗試做完美的前期設計那樣,寫完美的程式碼難道不是既浪費又沒有必要(也不可能實現)的麼?

“你不能寫出完美的軟體。是不是收到了傷害?並不。把它作為生活的公理接受它、擁抱它、慶祝它。因為完美的軟體不存在。在計算機的短暫歷史中從沒有人寫過完美的軟體。你不可能成為第一個。除非你接受這個事實,否則你最終會浪費時間和精力追逐不可能的夢想。”

Andrew Hunt,務實的程式設計師: 從熟練工到大師

一次性寫的程式碼不需要美觀優雅。但它必須是正確的、可以理解的 —— 因為絕不會改變的程式碼在系統的整個生命週期內可能仍然被閱讀很多次。它不需要乾淨並緊湊 —— 只要乾淨就夠了。程式碼中複製和貼上和其他小的裁剪是允許的,至少在某種程度上是這樣的。這些是永遠不需要打磨的程式碼。即使周圍的其他程式碼正在更改,這些也是不需要重構的程式碼(除非你需要更改它)。這是不值得花費額外時間的程式碼。

你一直在改變的程式碼怎麼樣了呢?糾結於程式碼風格以及提出最優雅的解決方案是浪費時間,因為這段程式碼可能會再次更改,甚至可能會在幾天或幾周內重寫。因此,每當你進行更改時,都會痴迷重構程式碼,或者沒有重構沒有改變的程式碼,因為它可能會更好。程式碼總是可以更好。但這並不重要。

重要的是:程式碼是否做了應該做的 —— 是正確的、可用的和高效的嗎?它可以處理錯誤和不良資料而不會崩潰 —— 或者至少可以安全地失敗?除錯容易嗎?改變是否容易且安全?這些不是美的主觀方面。這些是成功與失敗實際措施之間的差異。

務實編碼和重構

精益開發Lean Development的核心思想是:不要浪費時間在不重要的事情上。這應該提醒我們該如何編寫程式碼,以及我們如何重構它、審查它、測試它。

為了讓工作完成,只重構你需要的 —— Martin Fowler 稱之為機會主義重構opportunistic refactoring(理解、清理、童子軍規則 )和準備重構preparatory refactoring。足夠使改變更加容易和安全,而不是更多。如果你不改變那些程式碼,那麼它並不會如看起來的那麼重要。

在程式碼審查中,只聚焦在重要的事上。程式碼是否正確?有防禦機制嗎?是否安全?你能理解麼?改變是否安全?

忘記程式碼風格(除非程式碼風格變成無法理解)。讓你的 IDE 處理程式碼格式化。不要爭議程式碼是否應該是“更多的 OO”。只要它有意義,它是否適當地遵循這種或那種模式並不重要。無論你喜歡還是不喜歡都沒關係。你是否有更好的方式做到這一點並不重要 —— 除非你在教新接觸這個平臺或者語言的人,而且需要在做程式碼審查時做一部分指導。

寫測試很重要。測試涵蓋主要流程和重要的意外情況。測試讓你用最少的工作獲得最多的資訊和最大的信心。大面積覆蓋測試,或小型針對性測試 —— 都沒關係,只要一直在做這個工作,在編寫程式碼之前或之後編寫測試並不重要。

(不只是)程式碼無關

建築和工程方面的隱喻對軟體從未有效過。我們不是設計和建造幾年或幾代將保持基本不變的橋樑或摩天大樓。我們構建的是更加彈性和抽象、更加短暫的東西。程式碼寫來是被修改的 —— 這就是為什麼它被稱為“軟體”。

“經過五年的使用和修改,成功的軟體程式的原始碼通常完全認不出它原來的樣子,而一個成功建築五年後幾乎沒有變化。”

Kevin Tate,可持續軟體開發

我們需要將程式碼看作是我們工作的一個暫時的手工製品:

有時候面對更重要的事情時,我們會迷信程式碼。我們經常有一個錯覺,讓賣出的產品有價值的是程式碼,然而實際上可能是對該問題領域的瞭解、設計難題的進展甚至是客戶反饋。

Dan Grover,Code and Creative Destruction

迭代開發教會我們來體驗和檢驗我們工作的結果 —— 我們是否解決了這個問題,如果沒有,我們學到了什麼,我們如何改進?軟體構建從沒有止境。即使設計和程式碼是正確的,它們也可能只是一段時間內正確,直到環境要求再次更改或替換為更好的東西。

我們需要編寫好的程式碼:程式碼可以理解、正確、安全和可靠。我們需要重構和審查它,並寫出好的有用的測試,同時知道這其中一些或者所有的程式碼,可能會很快被拋棄,或者它可能永遠不會被再被檢視,或者它可能根本不會用到。我們需要認識到,我們的一些工作必然會被浪費,併為此而進行優化。做需要做的,沒有別的了。不要浪費時間嘗試編寫完美的程式碼。


作者簡介:

Jim Bird

我是一名經驗豐富的軟體開發經理、專案經理和 CTO,專注於軟體開發和維護、軟體質量和安全性方面的困難問題。在過去 15 年中,我一直在管理建立全球證券交易所和投資銀行電子交易平臺的團隊。我特別感興趣的是,小團隊在構建真正的軟體中如何有效率:在可靠性,效能和適應性極限限制下的高質量,安全系統。

 

相關文章