重構是一種針對現有程式碼進行結構調整的紀律技術,藉此改變其內部結構,而不改變其外部行為。
其核心是一系列小而保持行為轉換。每個轉換(稱為「重構」)只做一點點,但一系列此類轉換可以產生顯著的結構調整。由於每個重構都很小,因此出錯的可能性較低。在每次重構後,系統都會保持完全正常運作,降低在結構調整期間系統嚴重損壞的機率。
當一個軟體系統成功時,總是有必要持續增強它,以修復問題並加入新功能。畢竟,稱之為軟件是有原因的!但是程式碼庫的性質對進行這些變更的容易程度影響很大。很多時候,增強功能是一個接著一個疊加,以一種使得變更愈來愈難以進行的方式。隨著時間推移,新工作會減緩到如龜速般。要解決這個變更問題,重構程式碼非常重要,這樣一來,新增強功能就不會導致不必要的複雜性。
重構不是一個會顯示在專案計畫中的特殊任務。如果做好,它是編程活動的常規一部分。當我需要為程式碼庫加入新功能時,我會查看現有的程式碼,並考慮其結構是否能夠讓新變更變得直接。如果不能,我就會重構現有程式碼以讓這個新增功能變得容易。透過這種方式,我先進行重構,通常會發現這樣做比我沒有先進行重構還快。
完成變更後,我接著加入新功能。加入功能並讓其正常運作後,我常常會注意到 resulting 程式碼,雖然運作良好,但卻不如它能的那麼清楚。然後我就會將它重構成更新的樣貌,這樣一來,當我(或其他人在幾週後回到這個程式碼時,就不必花時間費心理解這個程式碼是如何運作的。
修改程式時,我常常會查看程式碼中的其他部分,因為我所需要做的很多事情可能已經編碼在程式中。這段程式碼可能是我可以輕鬆調用的函式,或隱藏在更大的函式內部。如果我難以理解這段程式碼,我就會重構它,這樣一來,下次我看它時就不必再苦惱。如果其中埋了一些我需要用到一些功能,我就會重構它,這樣一來,我就能夠輕鬆使用它。
當我在 90 年代後期撰寫重構的第一版時,支援重構的自動化工具少之又少。現在,許多語言的 IDE 都能自動執行許多常見的重構。這些工具真的是我的工具包中非常有價值的部分,它們能讓我更快地進行重構。但這些工具並非必需品 - 我經常在沒有工具支援的程式語言中工作,這種情況下,我依賴採取小步驟,並使用頻繁的測試來偵測錯誤。
本網站的主要內容是 重構線上目錄。其中列出了第二版中的重構,以及有關重構的摘要資訊。
要進一步瞭解重構,最自然的起點是我的重構書籍,現已發行第二版。我在 1997-9 年撰寫原始版本,當時重構是一種鮮為人知的技術。十八年後我更新時,重構已成為任何熟練程式設計師的例行工具。然而,新的人員會定期加入我們的職業,並需要瞭解重構。本書有助於他們學習,並讓經驗豐富的開發人員傳授他們的技能。
第二版中的範例都是用 JavaScript 撰寫的,但這些重構適用於任何語言。對於原始書籍(範例是以 Java 撰寫),許多開發人員發現直接拿取範例並將其應用於他們所使用的任何語言是很容易的。
如果你有這本書,你可以存取書籍的網路版本,這是標準版本。它包含書中沒有的幾個重構,以及一個擴充的範例。
在書中,我對「重構」做了以下定義
名詞:對軟體的內部結構所做的改變,使之更容易理解,而且在不改變其可觀察行為的情況下,修改成本更低
動詞:藉由套用一系列重構,在不改變其可觀察行為的情況下重新整理軟體結構。
重構並非清理程式碼的另一種說法 - 它特別定義了一項單一的技術,可改善程式碼庫的健全性。我使用「重整」作為重組程式碼的更通用術語,這可能包含其他技術。