代碼重構
程式碼重構是指在不創建新模組或功能的情況下直接改進程式碼,從而產生更用戶友好、更簡潔、更易讀的程式碼。
每次我們不進行重構就修改程式碼,程式碼腐化就會加劇並蔓延。程式碼腐化會讓我們感到沮喪,浪費時間,並無謂地縮短有用系統的壽命。在敏捷開發環境中,這可能決定我們能否準時完成迭代。
毫不留情地重構程式碼可以防止程式碼腐爛,保持程式碼易於維護和擴展。這種可擴展性是重構的原因,也是衡量重構成功與否的標準。但請注意,這只是“safe如果我們擁有像測試驅動開發(TDD)那樣龐大的單元測試套件,那麼對程式碼進行如此大規模的重構就顯得不切實際。因為在重構的每一步之後都無法執行這些測試,我們就很容易引入新的 bug。如果你採用的是真正的測試驅動開發(TDD),設計是持續演進的,那麼定期重構就必不可少,因為這是設計演進的方式。
代碼衛生
重構的常見比喻是邊煮飯邊打掃廚房。在任何一個每天要為不止幾個人準備幾頓複雜飯菜的廚房裡,你會發現清潔和整理工作幾乎是持續不斷的。總得有人負責保持餐具、鍋碗瓢盆、廚房本身、食物和冰箱的清潔和整齊。如果沒有這些,烹飪很快就會崩潰。在你自己的家中,你也能感受到哪怕是少量餐具清洗工作被拖延所帶來的嚴重後果:你試過把碗裡幹掉的可可脆片殘渣刮掉嗎?僅僅兩秒鐘的沖洗機會,就可能變成十分鐘的費力刮擦。
具體的“重構”
重構與無止盡地修改程式碼截然相反;它們是精確且有限的。馬丁·福勒的權威著作 書 該主題描述了 72 種具體的“重構”方法(例如,“提取方法”,它從一個方法中提取一段程式碼區塊,並為其建立一個新方法)。每種重構方法都將一段程式碼(程式碼區塊、方法或類別)從 22 種常見的「程式碼異味」狀態之一轉換為更最佳化的狀態。識別重構機會並正確實施重構需要一段時間才能掌握。
重構為模式
重構並非只發生在底層程式碼層面。在他最近的書中, 重構為模式Joshua Kerievsky 精闢地論證了重構才是將「四人幫」設計模式引入程式碼的最佳技術。他認為,模式常常被過度使用,並且過早地引入到系統中。他沿用了 Fowler 的原始方法,展示並命名具體的“重構”,即引導程式碼從 A 點到達 B 點的“秘訣”。 Kerievsky 的重構通常比 Fowler 的更高層次,並且經常以 Fowler 的重構作為建構模組。 Kerievsky 也引入了「朝向」模式重構的概念,描述了許多設計模式都有多種不同的實現方式,或者說不同的實現深度。有時你需要的模式比其他時候更全面,而本書將向你展示如何達到部分或全部目標。
重構流程
在測試優先的框架下,重構的流程與其他程式碼變更流程相同。首先,你需要寫自動化測試。然後,從最小的、可編譯、可運行且功能正常的獨立變更開始重構。盡可能地,在現有程式碼的基礎上並行添加變更。運行測試。接著,進行下一個小的獨立變更,再次執行測試。當重構完成且所有測試都順利通過後,再回頭移除舊的、有問題的平行程式碼。一旦所有測試都順利通過,重構就完成了。
IDE中的重構自動化
自動重構比手動重構容易得多。幸運的是,越來越多的整合開發環境 (IDE) 都內建了自動重構支援。例如,一款流行的 Java IDE 就是 日食其中包括不斷增加的自動重構。另一個我喜歡的功能是 IntelliJ IDEA歷史上,這其中甚至包含了更多的重構。在 .NET 領域,至少有兩個適用於 Visual Studio 2003 的重構工具插件,據稱未來版本的 Visual Studio 將內建重構支援。
在 Eclipse 或 IDEA 中重構程式碼時,只需選擇要重構的程式碼,從選單中選擇所需的特定重構選項,IDE 就會自動完成剩餘的工作。對於需要命名的元件,IDE 會跳出對應的對話方塊提示您輸入新名稱,以及其他類似的資訊。之後,您可以立即重新執行測試,確保變更沒有破壞任何功能。如果發現任何問題,您可以輕鬆撤銷重構並進行調查。