【重構】程序員
一、什麼是重構?算法
所謂 重構( refactoring) 是 這樣 一個 過程: 在不改變代碼外在行爲的前提下, 對代碼作出修改, 以改進程序的內部結構。數組
二、幾種基礎重構手法:性能優化
1)把某個字段,從一個類移至另 一個類。併發
2)把某些代碼提取成一個函數。 Extract Method.分佈式
3)把某個函數,從一個類移至另外一個類。Move Method.ide
三、每當看到長長的的函數,你就應當將它大卸八塊。代碼塊俞小,它的功能就俞容易管理。函數
四、重構步驟的本質:因爲每次修改的幅度都很小,因此任何錯誤都很容易發現。 你沒必要耗費大把時間調試, 哪怕你和我同樣粗心。性能
五、最好不要在另外一個對象的屬性基礎上運用 switch 語句。若是不得不使用,也應該在對象本身的數據上使用, 而不是在別人的數據上使用。測試
六、性能優化每每使代碼較難理解,但爲了獲得所需的性能你不得不那麼作。
七、若是沒有良好設計, 或許某 一段時間內你的進展迅速, 但惡劣的設計很快就讓你的速度慢下來。 你會把時間花在調試上面,沒法添加新功能。 修改時間愈來愈長, 由於你必須花愈來愈多的時間去理解系統、尋找重複代碼。 隨着你給最初程序打上一個又一個的補丁, 新特性須要更多代碼才能實現。 真是個惡性循環。
八、若是你爲求完成今天的任務而不擇手段, 致使不可能在明天完成明天的任務。
九、經常會有這樣的狀況: 你看到一段代碼有着長長的註釋,而後發現,這些註釋之因此存在乃是由於代碼很糟糕。
十、代碼首先是爲人寫的, 其次纔是爲計算機寫的。
十一、程序員很難記住那麼長的函數參數。
十二、模式是你但願到達的目標,重構則是到達之路。
1三、本書是在「單進程軟件」 這一大前提下考慮並介紹它們的。我很但願看到有人介紹用於併發和分佈式程序設計的重構技術。這樣的重構將是徹底不一樣的。
1四、重構的基本技巧—— 小步前進、頻繁測試—— 已經獲得多年的實踐檢驗。
【重構手法】
一、Parameterize Method。 若是有多個函數,他們的流程高度類似,而只是數值不同,則可將它們合併成一個函數,將動態的部分設置爲參數。
四、Inline Method.
【從新組織函數】
6.1)Extract Method(提取方法)。
6.2)Inline Method(內聯函數)。一個函數的本體很是矮小,能夠刪除函數,直接將函數body copy 過去。
6.3)Inline Temp。移除只賦值一次且只被使用一次的臨時變量。
6.4)Replace Temp with Query(以查詢取代臨時變量)。
6.5)Introduce Explaining Variable(引入解釋性變量)。將複雜表達式的結果放入一個臨時變量。
6.6)Split Temporary Variable(分解臨時變量)。若是一個變量不是循環變量,也不是累加變量,而被賦值二次及以上,則應當每次賦值新建一個臨時變量。
6.7)Remove Assignments to Parameters(移除對參數的賦值)。
6.8)Replace Method with Method Object。你有一個大型函數,其中對局部變量的使用使你沒法採用 Extract Method。將這個函數提取成爲一個對象,如此局部變量就變成爲對象內的字段,而後就能夠將這個大型函數拆分爲多個小函數了。
6.9) Substitute Algorithm(替換算法)。將某個算法替換成另外一個更清晰的算法。
【在對象之間搬移特性】
7.1)Move Method
7.2)Move Field
7.3)Extract Class(提煉類)。 某個類作了由多個類的事情。
7.4)Inline Class(將類內聯化)。某個類沒有作太多事情。將這個類的全部特性搬移到另外一個類中, 而後移除原類。
7.5)Hide Delegate(隱藏委託)
7.6)Remove MIddle Man(移除中間人)。某個類作了過多的簡單委託動做,讓客戶直接調用受託類。
7.7)Introduce Foreign Method(引入外加函數)
7.8 )Introduce Local Extension(引入本地擴展)
【從新組織數據】
8.1)Self Encapsulation Field(自封裝字段)。
8.2)Replace Data Value with Object(以對象取代數據值)。你有一個數據項,須要與其餘數據和行爲一塊兒使用纔有意義。將數據項變成對象。
8.3)Change Value to Reference(將值對象改成引用對象)。
8.4)Change Reference to Value(將引用對象改成值對象)。你有一個引用對象,很小且不可變,並且不易管理。將它變成一個值對象。
8.5)Replace Array with Object(以對象取代數組)。
8.6)Duplicate Observed Data(UI與Model拆分)。
8.7)Change Unidirectional Association to Bidirectional(將單向關聯改成雙向關聯)。
8.8)Change Bidirectional Association to Unidirectional(將雙向關聯改成單向關聯)。大量的雙向鏈接容易形成「殭屍」對象。
8.9)Replace Magic Number with Symbolic Constant(以字面常量取代魔法數)。
8.10)Encapsulation Field(封裝字段 )。
8.11)Encapsulate Collectoin(封裝集合)。有個函數返回一個集合。讓這個函數返回該集合的一個只讀副本, 並在這個類中提供添加/移除集合元素的函數。
8.12)Replace Record with Data Class(以數據類取代記錄)。
8.13)Replace Type Code with Class(以類取代類型碼)。類之中有一個數值類型碼,但它並不影響類的行爲。以一個新的類替換該數值類型碼。
8.14)Replace Type Code with Subclass(以子類取代類型碼)。
8.15)Replace Type Code with State/Strategy(以State/Strategy取代類型碼)。
8.16)Replace Subclass with Fields(以字段取代子類)。
【簡化條件表達式】
9.1)Decompose Conditional(分解條件表達式)。若是if...else...中語句過多,能夠將其中代碼分別提取成獨立的函數。
9.2)Consolidate Conditional Expression(合併條件表達式)。你有一系列條件測試,都和獲得相同結果,將這些測試合併爲一個測試,並提取成爲一個函數。
9.3)Consolidate Duplicate Conditional Fragments(合併重複的條件片斷)。在條件表達式每一個分支的重複代碼提取到條件表達式以外。
9.4)Remove Control Flag(移除控制標記)。以break語句取代控制標記。
9.5)Replace Nested Conditional with Guard Clauses(以衛語句取代嵌套條件表達式)。將多層嵌套的if...else...替換爲if。
9.6)Replace Conditional with Polymorphism(以多態取代條件表達式)。
9.7)Introduce Null Object(引入Null對象)。
9.8)Introduce Assertion(引入斷言)
【簡化函數調用】
10.1)Rename Method。首先考慮應該給這個函數寫上一句怎樣的註釋,而後想辦法將註釋變成函數名稱。
10.2)Add Parameter。
10.3)Remove Parameter。
10.4)Seprate Query From Modifier。任何有返回值的函數,都不該該有看獲得的反作用。
10.5)Parameterize Method。提取動態變量,成爲參數。
10.6)Replace Parameter with Explicit Methods。setValue => setheight & setwidth
10.7)Preserve Whole Object(保持對象完整)。讓函數參數具備動態性。
10.8)Replace Parameter with Methods。(以函數取代參數)
10.9)Introduce Parameter Object。有些參數老是很天然的成對出現。
10.10)Remove Setting Method(移除設值函數)。
10.11)Hide Method。隱藏曆來沒有被部用到過的函數。
10.12)Replace Constructor with Factory Method(以工廠函數取代構造函數)。你但願在建立對象時不 僅僅是作簡單的建構動做。
10.13)Encapsulate Downcast(函數封裝向下轉型)
10.14)Replace Error Code with Exception。以異常取代代碼錯誤。
10.15)Replace Exception with Test。異常只該被用於罕見的行爲,而不該該成爲條件檢察的替代品。
【處理歸納關係】
11.1)Pull Up Field
11.2)Pull Up Method
11.3)Pull Up Contructor Body()
11.4)Push Down Method(方法下移)
11.5)Push Down Field(字段下移)。
11.6)Extract Subclass(提煉子類)。類中的某些特性只被某些( 而非所有)實例用到。新建一個子類,將上面所說的那一部分特性移到子類 中。
11.7)Extract Superclass(提煉超類)。
11.8)Extract Interface(提煉接口)。兩個類的方法有部分相同,或多數客戶使用一個類的同一個子集。
11.9)Collapse Hierarchy(摺疊繼承體系)。超類和子類之間無太大區別時,使用此條。
11.10)Form Template Method。(塑造模板函數)。
11.11)Replace Inheritance with Delegation(以委託取代繼承)。某個子類只使用超類接口後部分,則使用此條。
11.12)Replace Delegation with Inheritance(以繼承取代委託)。
【大型重構】
12.1)Tease Apart Inheritance(橋模式拆解繼承體系)。
12.2)Converts Procedual Desing to Objects(將過程設計轉化爲面向對象)
12.3)Seperate Domain from Presentation(表現與數據分離)
12.4)Extract Hierarchy(提煉繼承體系)。某個類作了太多工做,其中一部分以條件表達式完成。能夠考慮拆成繼承體系。