什麼是程式碼重構與 YAGNI 原則?
程式碼重構 (Refactoring) 是一個在「不改變軟體外部行為」的前提下,透過修改內部結構來優化程式碼品質的過程。其目標在於降低 技術債 (Technical Debt)、提升可讀性與可維護性。而 YAGNI (You Aren’t Gonna Need It) 原則則是重構時最重要的心法之一,強調:除非當下真的需要,否則不要添加任何功能。這能有效避免「未來主義」導致的過度工程化。重構與 YAGNI 的結合,就像是軟體開發中的「斷捨離」,透過精確的修剪與簡化,確保專案架構保持輕量,讓開發者能更專注於當下的商業價值,而非浪費時間在那些「預防萬一」卻永不使用的死程式碼上。
為什麼需要重構:識別程式碼壞味道
在我們的生活中,有許多重要的事情需要我們時常檢討和改進,這個過程被稱為斷捨離。在軟體開發中,這就是程式碼重構 (Refactoring) 的核心。
當程式碼變得複雜難懂時,往往是因為產生了程式碼壞味道 (Code Smells)。這些壞味道會隨著時間累積成為技術債 (Technical Debt),最終導致系統難以擴展。以下是我們在進行斷捨離時應優先移除的項目:
- 過長函式 (Long Method):需要超級多參數才能執行的函式。
- 寫作文般的註解:若程式碼本身清晰,註解應是多餘的。
- 過度複雜的條件判斷:複雜的邏輯分支讓人難以閱讀。
- 硬編碼 (Magic Numbers):寫死的數值或設定檔。
- 未來主義 (Speculative Generality):覺得以後有機會用到,但現在完全沒作用的程式碼。
- 過多的中間產物:更不該把中間產物當結果。
- 複製貼上 (Duplicate Code):缺乏元件化思維的產物。
- 做到一半且短期不會完成的功能。
1 | // 過於複雜的條件判斷範例 |
重構是什麼:簡化與重新組織
程式的斷捨離是一個重構的過程。重構能讓程式碼變得更加簡潔、容易閱讀和維護,就像整理混亂的房間。第一步就是將不必要的部分丟棄,重新組織與排放。
斷捨離是一個檢討和簡化生活的過程。以 addNumbers 函式為例,我們常會為了追求「防呆」而加入過多的型別檢查,反而模糊了程式的意圖。
1 | // 重構前:過度保護與冗餘邏輯 |
該減少的是過多的型別檢查,JavaScript 會自動轉型,而多層的 else block 往往是不必要的。
1 | // 重構後:回歸本質 |
不管在什麼層面,要避免過度和極端,過度的追求會導致不平衡和不和諧。其中有個「水」的比喻很好:水能適應不同的形狀,不爭鬥也不過於強硬,即使不強硬,卻也可以鑿穿石頭。當我們減少欲望,更可以獲得內在的平靜。
YAGNI (You Aren’t Gonna Need It!)
YAGNI 是軟體開發中的重要原則,強調在當下不要添加不必要的功能。
對於人生來說,我們在同個時間只需要一條牙膏跟一隻牙刷,如果依照每層樓去擺放一樣的物品,一個家裡面就會擁有好幾組,但我們其實只需要一組不是嗎?整理東西的時候,我們就要先把同一類的東西先集中,就像我就有好多無線耳機跟喇叭,散落在學校、工作室、浴室,但搬回家後就多了許多沒用到的。
從《道德經》的觀點來看,YAGNI 是實踐節制與簡單的原則。它提醒我們不要過於追求完美,而應保持精簡,關注當下需求即可。透過移除冗餘程式碼,我們能有效降低技術債,讓專案架構保持靈活與輕巧。
YAGNI 提醒我們不應該為了「未來的可能」增加多餘的東西。好好解決當下的需求,這才是最有效率的開發路徑。
FAQ:重構與 YAGNI 常見問題
Q1:重構會不會引入新的 Bug?該如何降低風險?
A:會。 所以重構的前提必須具備完整的 自動化測試 (Unit Tests)。遵循「紅燈、綠燈、重構 (Red-Green-Refactor)」循環:先確保功能在現有測試下是綠燈,進行小步重構後,再次執行測試確保依然是綠燈。如果沒有測試保護,那不叫重構,叫「搏命」。
Q2:YAGNI 原則與「預留系統彈性」衝突嗎?
A:YAGNI 針對的是「具體功能的擴充」,而非「架構的靈活性」。好的架構應該是「容易被修改的」,而不是「預先寫好所有可能」。例如,您可以透過 依賴反轉原則 (DIP) 讓系統易於擴展,但不需要現在就幫它寫好 5 種不同資料庫的連接器。
Q3:什麼是重構的最佳時機?
A:推薦採用 「三層營地法 (Boy Scout Rule)」:在您要開發新功能或修復 Bug 時,順手重構受影響區域的程式碼。如果您發現程式碼壞味道已經嚴重阻礙了開發速度(例如:新增一個欄位要改 10 個檔案),那就是該啟動「專項重構」的時刻了。
喜歡這篇文章,請幫忙拍拍手喔 🤣