1 Decompose Conditional(分解條件表達式)
從復(fù)雜表達式if-then-else三個段落中分別提煉出獨立函數(shù)锅论。
Motivation:降低表達式邏輯復(fù)雜度赶熟,突出分支作用灭衷。
做法:
- 將if段落提煉出來,構(gòu)成一個獨立函數(shù)譬猫。
- 將then段落和else段落都提煉出來,各自構(gòu)成一個獨立函數(shù)县遣。
2 Consolidate Conditional Expression(合并條件表達式)
一系列條件表達式虱咧,得到的結(jié)果相同。將這些測試合并為一個條件表達式种樱,并將這個條件表達式提煉成一個獨立函數(shù)蒙袍。
Motivation:合并多個并列條件成一個明確的條件審查可以使檢查用意更清楚俊卤;這項重構(gòu)可以為Extract Method做準(zhǔn)備。
- 確定這些條件語句都沒有副作用害幅。
- 使用恰當(dāng)?shù)倪壿嫴僮鞣校瑢⒁幌盗邢嚓P(guān)條件表達式合并為一個。
- 編譯以现,測試狠怨。
- 對合并后的條件表達式使用Extract Method。
3 Consolidate Duplicate Conditional Fragments(合并重復(fù)條件片段)
在條件表達式中有相同代碼邑遏,將代碼提取到條件表達式之外佣赖。
4 Remove Control Flag(移除控制標(biāo)記)
在一系列布爾表達式中,某個變量帶有控制標(biāo)記作用记盒,以break或return取代控制標(biāo)記憎蛤。
Motivation:用break和continue語句的原因是用它們跳出復(fù)雜的條件語句可以使條件變得清晰得多。
做法:
- 找出讓你跳出這段邏輯的判斷標(biāo)記纪吮。
- 找出對標(biāo)記變量賦值的語句俩檬,替代以恰當(dāng)?shù)腷reak語句或continue語句。
- 每次替換后碾盟,編譯并測試豆胸。
5 Replace Nested Conditional with Guard Clauses(以衛(wèi)語句取代嵌套條件表達式)
條件邏輯使人難以看清正常的執(zhí)行路徑。使用衛(wèi)語句表現(xiàn)所有你特殊情況巷疼。
Motivation:條件表達式一共有兩種形式:1.所有分支都屬于正常行為晚胡。2.條件表達式提供的答案中只有一種是正常行為,其他都不常見嚼沿。如果分支都屬于正常行為估盘,使用if-else挺好的;如果某個條件極其罕見骡尽,就應(yīng)該單獨檢查該條件遣妥,并在該條件為真時立即返回。這樣單獨的檢查常常被稱為“衛(wèi)語句”攀细。衛(wèi)語句的精髓在于給一條分支以特別的重視箫踩。
- 對于每個檢查,放進一個衛(wèi)語句谭贪。ps:衛(wèi)語句要么就從函數(shù)中返回境钟,要不就拋出一個異常。
- 每次講條件檢查替換成衛(wèi)語句后俭识,編譯并測試慨削。
6 Replace Conditional with Polymorphism(以多態(tài)取代條件表達式)
有根據(jù)類型字段來選擇函數(shù)不同的函數(shù)行為。將這個條件表達式的每個分支放進一個子類內(nèi)的覆寫函數(shù)中,然后將原始函數(shù)聲明為抽象函數(shù)缚态。
Motivation:使用條件表達式磁椒,使用的是硬編碼,很難對條件表達式進行變化玫芦。
做法:
在做這個重構(gòu)首發(fā)之前浆熔,必須得有繼承結(jié)構(gòu),這種繼承結(jié)構(gòu)有兩種手段去建立:Replace Type Code with Subclasses 和 Replace Type Code with State/Strategy桥帆。
- 如果要處理的條件表達式是一個更大函數(shù)中的一部分蘸拔,首先對條件表達式進行分析,然后使用extract Method把它提煉到一個獨立函數(shù)中环葵。
- 如果有必要调窍,使用Move Method將條件表達式放置到繼承結(jié)構(gòu)的頂端。
- 任選一個子類张遭,在其中建立一個函數(shù)邓萨,使之覆寫超類中容納條件表達式的那個函數(shù)。將與該子類先關(guān)的條件表達式分支賦值到新建函數(shù)中菊卷,并對它進行適當(dāng)調(diào)整缔恳。
- 編譯,測試洁闰。
- 在超類刪除到表達式內(nèi)被賦值的分支歉甚。
- 編譯,測試扑眉。
- 重復(fù)上述的過程纸泄,知道所有分支都被移動到子類內(nèi)。
- 將超類之中容納條件表達式的函數(shù)聲明為抽象函數(shù)腰素。
7 Introduce Null Object(引入Null對象)
你需要再三檢查某對象是否為null聘裁。將null值替換為null對象。
Motivation:這是踐行多態(tài)的一個非常好的方案弓千。試想衡便,如果對每個對象,都必須判斷其是否為null洋访,然后才能進行下一步的行為镣陕。那么系統(tǒng)中一定會運行大量的判斷代碼,這是就大量的重復(fù)代碼姻政。
做法:
- 為源類建立一個子類呆抑,使其行為就像源類的null版本。在源類和null子類中都加上isNull()扶歪,前者返回false理肺,后者返回true。
- 編譯善镰。
- 找出所有索求源對象卻獲得一個null的地方妹萨。修改這些地方,使它們調(diào)用isNull()函數(shù)炫欺。
- 編譯乎完,測試。
- 找出這樣的程序點:如果對象不是null品洛,做A動作树姨,否則B動作。
- 對于每一個上述弟弟昂桥状,在null類中覆蓋A動作帽揪,使其行為和B相同。
- 使用上述被覆寫的動作辅斟,然后刪除對象是否為null的條件測試转晰。編譯并測試。
tips:其實這樣的方式可以被認(rèn)為是特例類模式士飒,用特例來減少處理特例的開銷查邢。
8 Introduce Assertion
用斷言明確表明對程序狀態(tài)的假設(shè)。
Motivation:可以幫助我們理解某些條件對程序是極其重要的酵幕。斷言可以幫助程序閱讀者閱讀代碼扰藕,可以幫助調(diào)試程序。
做法:
只要程序源不犯錯芳撒,斷言就應(yīng)該不會對系統(tǒng)運行造成任何影響邓深,所以加入斷言永遠(yuǎn)不會影響程序的行為。斷言一定要用來判斷一定為真的條件笔刹。