程式碼重構指對軟體程式碼做一些改動以增加可讀性或者簡化程式碼結構而不影響輸出結果。 軟體重構需要藉助重構工具完成，重構工具能夠修改程式碼同時修改所有引用該程式碼的地方。在極限程式設計的方法學中，重構需要單元測試來支援。 重構程式碼 thumb 圖一 thumb 圖二 在軟體工程學裡，重構程式碼一詞通常是指在不改變程式碼的外部行為情況下而修改原始碼。在極限程式設計或其他敏捷方法學中，重構常常是軟體開發中的一部分：開發者輪流增加新的測試和功能，並重構程式碼來增進程式碼間的清晰性和一致性。同時，自動化的單元測試保證了重構後的程式碼仍然能夠正常運作。 重構既不修正錯誤，也不增加新的功能。它的目的是用於提高程式碼的可讀性或者改變程式碼內部結構與設計或者刪除死碼，使其在將來更容易進行維護和開發。重構程式碼可以存在於結構層面或是語意層面，但前提是不影響程式碼在轉換前後的功能。一種進行重構的典型案例是：一個程式在現有的邏輯結構下難以加入新的功能，因此開發人員可能會對程式碼進行重構，以便日後繼續開發。 一個重構的小范例是修改一個變數的名稱使其具有更明確的含義，例如從單個字母的「i」重構為「interestRate」（利率，圖一）。一個較複雜的重構的例子是把一段 if 區塊中的程式碼變為一個子程式（圖二）。更復雜一點的重構是用多型性來替換 if 條件式。進一步還可重新設計程式的演算法。在重構中最關鍵的是去有意地「清理」程式碼，把不同的功能分開，然後對重構後的程式碼進行測試（任何對程式碼的編輯都有可能引發錯誤）。新的實現方法需要切合實際地改善現有設計，並且不改變原軟體的功能或行為。 難點 程式碼重構也面臨諸多的挑戰。首先，對重構長遠的影響需要在重構後才能進行深入研究和追蹤。其次，重構某些底層業務邏輯或是資料庫架構幾乎是不可能的。最後，對介面造成影響的重構可能造成程式開發上的困境。例如，程式設計師若改變某介面中的方法名稱，除非他或她要對所有客戶端中連結到舊方法名的參考都加以編輯，否則就只能繼續維護使用舊方法名的介面，並另外建立舊名對新名的對映。 源流 首先使用「重構」一辭於出版文獻是於一篇文章：《Refactoring An Aid in Designing Application Frameworks and Evolving ObjectOriented Systems Proceedings of the Symposium on Object Oriented Programming Emphasizing Practical Applications SOOPPA》，1990 年 9 月，由 William F Opdyke 與 Ralph E Johnson 聯名出版。William Opdyke 的博士論文於「重構：物件導向框架」，伊利諾大學，1992 年出版。「重構」術語幾乎至其後確定。 重構這個術語是從數字與多項式的因式分解類比而來英文重構（refactor）為 重新（re）與 （因式）分解（factor）兩單詞的結合。如，x2 1 可以被分解為 x 1x 1，這樣更好的整理並展示了式子的性質（例如式子擁有兩個根 1 和1）。同樣，在軟體重構中，結構上的改變通常會揭示原始碼中曾經「隱藏」的內部結構。 上面多項式的例子很好地展示了「重構」的思路。但是，一個多項式的不同表示形式並沒有優劣之分，它們展現了多項式的不同性質。在不同情況下適合的表達形式不同，並且還會隨著使用者的個人習慣或理解變化。這個問題於軟體開發領域亦然：個別程式員可能對某既定演演算法的理想結構會有不同的意見。 重構方法簡單列表 下面是不完整的程式碼重構清單。長一點的清單可以在福勒的重構書找到。因為研究者們繼續努力不懈的發明以及實現重構，完整清單可能永遠都不存在。 （Encapsulate Field） 將僅限於本 zhcn 類；zhtw 類別； 使用的變數重寫成私有（private）成員變數，並提供訪問方法（accessor method）。這種重構方式可以將與外部呼叫者無關的變數隱藏起來，減少程式碼的耦合性，並減少意外出錯的機率。 提取方法（Extract Method） 意思是將大段程式碼中的一部分提取後，構成一個新方法。這種重構可以使整段程式的結構變得更清晰，從而增加可讀性。這也對函式（Function）通用。 （Generalize Type） 將多個 zhcn 類；zhtw 類別； 函式共用的型別抽象出可以公用的基類（base class），然後利用多型性追加每個 zhcn 類；zhtw 類別； 函式需要的特殊函式。這種重構可以讓結構更加清晰，同時可以增加程式碼的可維護性。 函式歸父（Pull Up） 或譯函式上移，指的是方法從子類移動到父類。 函式歸子（Push Down） 或譯函式下移，指的是方法從父類移動到子類。 （Rename Method） 將方法名稱以更好的表達它的用途。 重構方法 重構前 重構後 封裝成員變數 class SomeClass public int memberA class SomeClass private int memberA public int getMemberA public void setMemberA int a 方法提取 void Process MyDataSet mds Step 1 int result 0 if mdsisReady int data1 mdsparam 0 int data2 mdsparam 1 Preprocess result data1 data2 Step 2 void Process MyDataSet mds Step 1 int result 0 if mdsisReady result CalculateMDS mdsparam 0 mdsparam 1 Step 2 int CalculateMDS int data1 int data2 Preprocess return data1 data2 一般化型別 class Rectangle private int w h public double Area return wh class Triangle private int w h public double Area return wh2 class Polygon private int w h public virtual double Area 0 class Rectangle public Polygon double Area return wh class Triangle public Polygon double Area return wh2 方法更名 public double f double m double a public double calculateForce double mass double acceleration 程式碼重構自動化 許多軟體編輯器與整合環境支援重構自動化，又稱為重構瀏覽器。列舉如下： IntelliJ IDEA（Java 專用） Eclipse 給 Java 用的開發包（JDK） NetBeans（Java 專用） Visual Studio 2005（NET 專用） CodeGear Delphi Bicycle Repair Man （Python 專用，可與 emacs 與 vi 共用） Refactoring Browser，Smalltalk 專用 硬體重構 儘管程式碼重構一詞最初只用於軟體程式碼的重構，但近年來，硬體描述語言也出現了相應的程式碼重構的概念。硬體重構（hardware refactoring）是對硬體描述語言中的程式碼進行重構的簡稱。由於一般認為硬體描述語言與傳統程式語言有較大的區別，因此硬體重構被視為與傳統的程式碼重構不同的領域。 研究者已經提出了類比電路硬體描述語言（如 VHDLAMS）所使用的自動化重構方法。根據他們的研究，硬體重構會在保持原本程式碼的模擬結果的同時，增進行為模型的可理解性、可擴充套件性和可重用性，並使得後續自動化編譯過程的邏輯綜合步驟可以產生更加符合預期的結構表示。此外，Synopsys 公司的 Mike Keating 也研究了手動進行的數位電路硬體描述語言的重構。他所研究的目標是使複雜的硬體系統更易於理解，從而提高設計人員的生產力。 註釋 參考文獻 引用 來源 書籍 馬丁福勒：《重構：改進現有程式碼的設計》，AddisonWesley Professional 1999 ISBN 9780201485677 William C Wake：《重構練習冊》，AddisonWesley ISBN 9780321109293 Joshua Kerievesky：《重構到模式》，AddisonWesley ISBN 9780321213358 外部連結 什麼是重構？（c2com 文獻） Martin Fowler 的關於重構的主頁 William F Opdyke 在 1993 年發表的博士論文 面向方面的重構，Ramnivas Laddad 著 軟體重構的縱覽 ，Tom Mens 和 Tom Tourwé 著 如何編寫難以維護的程式碼 ，Roedy Green 著 重構工具 重構 alphabetical list 重構為模式的目錄 重構 Java 程式碼 通用重構連結 微控制器軟體的重構 Refuctoring 重構的反面（來自 Waterfall2006 會議的嘲諷） 重構文獻 重構相關短文 參見 程式碼評審 軟體同行評審 軟體設計模式 關注點分離 測試驅動開發 軟體智慧 Category 軟體工程 Category 計算機程式設計 Category 極限程式設計