[1] 從新組織你的函數html
1.1 Extract Method(提煉函數)算法
有一段代碼能夠被組織在一塊兒並獨立出來,將這段代碼放進一個獨立函數中,並讓函數名稱解釋該函數的用途。編程
1.2 Inline Method(將函數內聯化)數組
一個函數的本體與名稱一樣清楚易懂。在函數的調用點插入函數本體,而後移除該函數。ide
1.3 Inline Temp(將臨時變量內聯化)函數
有一個臨時變量,只被一個簡單表達式賦值一次,而它妨礙了其餘重構手法。將全部對該變量的引用動做,替換爲對它賦值的那個表達式自身。post
1.4 Replace Temp With Query(以查詢取代臨時變量)測試
以一個臨時變量保存某一表達式的運算結果。將這個表達式提煉到一個獨立函數中。將這個臨時變量的全部引用點替換爲對新函數的調用。此後,新函數就能夠被其餘函數使用。spa
1.5 Introduce Explaining Variable(引入解釋性變量)設計
程序中有一個複雜表達式。將該複雜表達式(或其中一部分)的結果放進一個臨時變量,以此變量名稱來解釋表達式用途。
1.6 Split Temporary Variable(分解臨時變量)
有某個臨時變量被賦值超過一次,它既不是循環變量,也不被用於收集計算結果。針對每次賦值,創造一個獨立、對應的臨時變量。
1.7 Remove Assignments to Paramete (移除對參數的賦值動做)
代碼對一個參數進行賦值。以一個臨時變量取代該參數的位置。
1.8 Replace Method with Method Object(以函數對象取代函數)
有一個大型函數,其中對局部變量的使用使你沒法採用[1.1提煉函數]。
將這個函數放進一個單獨對象中,如此一來局部變量就成了對象內的字段。
而後,你能夠在同一個對象中將這個大型函數分解爲多個小型函數。
1.9 Substitute Algorithm(替換你的算法)
想要把某個算法替換爲另外一個更清晰的算法。將函數本體替換爲另外一個算法。
[2] 在對象之間移動特性
2.1 Move Method(搬移函數)
在程序中,若是有個函數與其所駐之類的另一個類進行更多交流,調用後者或被後者調用。
在該函數最常引用的類中創建一個有着相似行爲的新函數。
將舊函數變成一個單純的委託函數,或將舊函數徹底移除。
2.2 Move Field(搬移字段)
程序中,某個字段被其所駐類以外的另外一個類更多的用到。在目標類新建一個字段,修改源字段的全部用戶,令他們改用新字段。
若是發現,對於一個字段,在其所駐類以外的另外一個類中有更多函數使用了它,我就會考慮搬移這個字段。
2.3 Extract Class(提煉類)
某個類作了應該由兩個類作的事。創建一個新類,將相關的字段和函數從舊類搬移到新類。
2.4 Inline Class(將類內聯化)
若是某個類沒有作太多事情,將這個類中的全部特性移到另一個類中,而後刪除原類。
2.5 Hide Delegate(隱藏「委託關係」)
客戶經過一個委託類來調用另外一個對象。
在服務類上創建客戶所需的全部函數,用以隱藏委託關係。
2.6 Remove Middle Man(移除中間人)
某個類作了過多簡單委託工做;讓客戶直接調用委託類。
2.7 Introduce Foreign Method(引入外加函數)
你須要爲提供服務的類增長一個函數,但你沒法修改這個類。在客戶類中創建一個函數,並以第一參數形式傳入一個服務類實例。
2.8 Introduce Local Extension(引入本地擴展(子類或包裝類))
你須要爲服務類提供一些額外函數,但你沒法修改這個類。創建一個新類,使它包含這些額外函數。讓這個擴展品成爲源類的子類或包裝類。
[3] 從新組織你的數據
3.1 Self Encapsulate Field(自封裝字段)
直接訪問一個字段,但與字段之間的耦合關係逐漸變得笨拙。爲這個字段創建取值/設值函數,而且只以這些函數來訪問字段。
3.2 Replace Data Value with Object(以對象取代數據值)
有一個數據項,須要與其餘數據和行爲一塊兒使用纔有意義。將數據項變爲對象。
3.3 Change Value to Reference(將實值對象改成引用對象)
從一個類衍生出許多彼此相等的實例,但願將它們替換爲同一個對象。將這個值對象變爲引用對象。
3.4 Change Reference to Value(將引用對象改成實值對象)
有一個引用對象,很小且不可變,並且不易管理、將它變成一個值對象。
3.5 Replace Array with Object(以對象取代數組)
有一個數組 ,其中的元素各自表明不一樣的東西。以對象替換數組。對於數組中的每一個元素,以一個字段來表示。
3.6 Duplicate Observed Data(複製「被監視數據」)
有一些領域數據置身於GUI控件中,而領域函數須要訪問這些數據。將該數據複製到一個領域對象中。
創建一個Observer模式,用以同步領域對象和GUI對象內的重複數據。
3.7 Change Unidirectional Association to Bidirectional(將單向關聯改成雙向)
兩個類都須要使用對方特性,但其間只有一條單向鏈接。添加一個反向指針,並使修改函數可以同時更新兩條鏈接。
3.8 Change Bidirectional Association to Unidirectional(將雙向關聯改成單向)
兩個類之間有雙向關聯,但其中一個類現在再也不須要另外一個類的特性。去除沒必要要的關聯。
3.9 Replace Magic Number with Symbolic Co tant (以符號常量/字面常量取代魔法數)
有一個字面數值,帶有特別含義。創造一個常量,根據其意義爲它命名,並將上述的字面數值替換爲這個常量。
3.10 Encapsulate Field(封裝字段)
類中存在一個public字段,將它聲明爲private,並提供相應的訪問函數。
3.11 Encapsulate Collection(封裝集合)
有個函數返回一個集合。讓這個函數返回該集合的一個只讀副本,並在這個類中提供添加/移除集合元素的函數。
3.12 Replace Record with Data Class(以數據類取代記錄)
你須要面對傳統編程環境中的記錄結構。爲該記錄建立一個「啞」數據對象。
3.13 Replace Type Code with Class(以類取代型別碼)
類中有一個數值類型碼,但它並不影響類的行爲。以一個新的類替換該數值類型碼。
3.14 Replace Type Code with Subclasses (以子類取代類型碼)
有一個不可變的類型碼,它會影響類的行爲。以子類取代這個類型碼。
3.15 Replace Type Code with State/Strategy (以State/Strategy狀態對象取代類型碼)
有一個類型碼,它會影響類的行爲。但你沒法經過繼承手法消除它。以狀態對象取代類型碼。
3.16 Replace Subclass with Fields(以字段取代子類)
各個子類的惟一差異只在」返回常量數據「的函數身上。修改這些函數,使它們返回超類中的某個(新增)字段,而後銷燬子類。
[4] 簡化條件表達式
4.1 Decompose Conditional(分解條件式)
有一個複雜的條件(if-then-else)語句。從if、then、else三個段落中分別提煉出獨立函數。
4.2 Co olidate Conditional Expression(合併條件式)
有一系列條件測試,都獲得相同的結果。將這些測試合併爲一個條件表達式,並將這個條件表達式提煉成爲一個獨立函數。
4.3 Co olidate Duplicate Conditional Fragments (合併重複的條件執行片斷)
在條件表達式的每一個分支上有着相同的一段代碼。將這段重複代碼搬移到條件表達式以外。
4.4 Remove Control Flag(移除控制標記)
在一系列布爾表達式中,某個變量帶有「控制標記」(control flag)的做用。以break語句或return語句取代控制標記。
4.5 Replace Nested Conditional with Guard Clauses (以衛語句取代嵌套條件式)
函數中的條件邏輯令人難以看清正常的分支執行路徑。使用衛語句表現全部特殊狀況。所
謂衛語句,若是某個條件極其罕見,就應該單獨檢查該條件,並在該條件爲真時馬上從函數中返回。這樣的單獨檢查經常被稱爲「衛語句」。
4.6 Replace Conditional with Polymorphism(以多態取代條件式)
有個條件表達式,它根據對象類型的不一樣而選擇不一樣的行爲。
將這個條件表達式的每一個分支放進一個子類內的覆寫函數中,而後將原始函數聲明爲抽象函數。
4.7 Introduce Null Object(引入NULL對象)
你須要再三檢查某個對象是否爲NULL。將NULL值替換爲NULL對象。
4.8 Introduce Assertion(引入斷言)
某一段代碼須要對程序狀態作出某種假設。以斷言明確表現這種假設。
[5] 簡化函數調用
5.1 Rename Method(從新命名函數)
函數名稱未能揭示函數的用途。修改函數名稱。
5.2 Add Parameter(添加參數)
某個函數須要從調用端獲得更多的信息。爲此函數添加一個對象參數,讓該對象帶進函數所需的信息。
5.3 Remove Parameter(移除參數)
函數本體再也不須要某個參數。將該參數去除。
5.4 Separate Query from Modifier(將查詢函數和修改函數分離)
某個函數既返回對象狀態值,又修改對象狀態。
創建兩個不一樣的函數,其中一個負責查詢,另外一個負責修改。
5.5 Parameterize Method(令函數攜帶參數)
若干函數作了相似的工做,但在函數本體中卻包含了不一樣的值。
創建單一函數,以參數表達那些不一樣的值。
5.6 Replace Parameter with Explicit Methods(以明確函數取代參數)
有一個函數,其中實現徹底取決於參數值而採起不一樣行爲。
針對該參數的每個可能值,創建一個獨立函數。
5.7 Preserve Whole Object(保持對象完整)
從某個對象中取出若干值,將它們做爲某一次函數調用時的參數。改成傳遞整個對象。
5.8 Replace Parameter with Method(以成員函數取代參數)
一個對象調用某個函數,並將所得結果做爲參數,傳遞給另外一個函數,而接受該參數的函數自己也可以調用前一個函數。
讓參數接受者去除該項參數,並直接調用前一個函數。
5.9 Introduce Parameter Object(引入參數對象)
某些參數老是很天然地同時出現。以一個對象取代這些參數。
5.10 Remove Setting Method(移除設值函數)
類中的某個字段只在對象建立時被設值,而後就再也不改變。去掉該字段的全部設值函數。
5.11 Hide Method(隱藏你的函數)
類中有一個函數,歷來沒有被其餘任何類用到。將這個函數修改成private私有訪問權限。
5.12 Replace Co tructor with Factory Method(以工廠方法取代構造函數)
你但願在建立對象時不只僅是作簡單的構建動做。將構造函數替換爲工廠函數。
5.13 Encapsulate Downcast(封裝「向下轉型」動做)
某個函數返回的對象,須要由函數調用者執行向下轉型。
那麼,將向下轉型動做移到函數中(即封裝)。這樣函數調用者不用再考慮轉換對象類型。
5.14 Replace Error Code with Exception(以異常取代錯誤碼)
某個函數返回一個特定的代碼,用以表示某種錯誤狀況。改用異常。
5.15 Replace Exception with Test(以測試取代異常)
面對一個調用者能夠預先檢查的條件,你拋出了一個異常。修改調用者,使它在調用函數以前先作檢查。
[6] 處理歸納關係
6.1 Pull Up Field(字段上移)
即成員變量上移。兩個子類擁有相同的字段,將該字段移至基類。
6.2 Pull Up Method(函數上移)
即成員函數上移。兩個子類擁有相同的函數(產生徹底相同的結果),將該函數移至基類。
6.3 Pull Up Co tructor Body(構造函數本體上移)
在各個子類中擁有一些構造函數,它們的本體幾乎徹底一致。在基類中新建一個構造函數,並在子類構造函數中調用它。
6.4 Push Down Method(函數下移)
即成員函數下移。基類中某個函數只與部分(而非所有)子類有關,將這個函數移到相關的那些子類中去。
6.5 Push Down Field(字段下移)
即成員變量。基類中某個字段只與部分(而非所有)子類有關,將這個字段移到相關的那些子類中去。
6.6 Extract Subclass(提煉子類)
類中的某些特性只被某些(而非所有)實例用到。新建一個子類,將上面所說的那一部分特性移到子類中。
6.7 Extract Superclass(提煉超類)
兩個類有類似特性。爲這兩個類創建一個基類,將相同特性移至基類。
6.8 Extract Interface(提煉接口)
若干客戶使用類接口中的同一子集,或者兩個類的接口有部分相同。將相同的子集提煉到一個獨立接口中。
6.9 Collapse Hierarchy(摺疊繼承體系)
基類和子類無太大區別,將它們合爲一體。
6.10 Form Template Method(塑造模板函數)
有一些子類,其中相應的某些函數以相同順序執行相似的操做,但各個操做的細節上稍有不一樣。
將這些細節稍不一樣的操做分別放進獨立的函數中,並保持它們都有相同的函數名,因而原函數也就變得相同了。
而後,將原函數上移至基類中。
6.11 Replace Inheritance with Delegation(以委託取代繼承)
某個子類只使用基類接口中一部分,或者根本不須要繼承而來的數據。在子類中新建一個字段用以保存基類:調整子類函數,令它改而委託基類。而後去掉二者之間的繼承關係。
6.12 Replace Delegation with Inheritance(以繼承取代委託)
在兩個類之間使用委託關係,並常常爲整個接口編寫許多極其簡單的委託函數。讓委託類繼承受託類。
[7] 大型重構
7.1 Tease Apart Inheritance(疏理並分解繼承體系)
7.2 Convert Procedural Design to Objects(將過程化設計轉化爲對象設計)
7.3 Separate Domain from Presentation(將領域和表述/顯示分離)
7.4 Extract Hierarchy(提煉繼承體系)
Good Good Study, Day Day Up.
順序 選擇 循環 總結