1 Decompose Conditional(分解條件表達(dá)式)
從復(fù)雜表達(dá)式if-then-else三個(gè)段落中分別提煉出獨(dú)立函數(shù)。
Motivation:降低表達(dá)式邏輯復(fù)雜度,突出分支作用。
做法:
- 將if段落提煉出來,構(gòu)成一個(gè)獨(dú)立函數(shù)。
- 將then段落和else段落都提煉出來,各自構(gòu)成一個(gè)獨(dú)立函數(shù)。
2 Consolidate Conditional Expression(合并條件表達(dá)式)
一系列條件表達(dá)式,得到的結(jié)果相同。將這些測試合并為一個(gè)條件表達(dá)式,并將這個(gè)條件表達(dá)式提煉成一個(gè)獨(dú)立函數(shù)。
Motivation:合并多個(gè)并列條件成一個(gè)明確的條件審查可以使檢查用意更清楚;這項(xiàng)重構(gòu)可以為Extract Method做準(zhǔn)備。
- 確定這些條件語句都沒有副作用。
- 使用恰當(dāng)?shù)倪壿嫴僮鞣?,將一系列相關(guān)條件表達(dá)式合并為一個(gè)。
- 編譯,測試。
- 對(duì)合并后的條件表達(dá)式使用Extract Method。
3 Consolidate Duplicate Conditional Fragments(合并重復(fù)條件片段)
在條件表達(dá)式中有相同代碼,將代碼提取到條件表達(dá)式之外。
4 Remove Control Flag(移除控制標(biāo)記)
在一系列布爾表達(dá)式中,某個(gè)變量帶有控制標(biāo)記作用,以break或return取代控制標(biāo)記。
Motivation:用break和continue語句的原因是用它們跳出復(fù)雜的條件語句可以使條件變得清晰得多。
做法:
- 找出讓你跳出這段邏輯的判斷標(biāo)記。
- 找出對(duì)標(biāo)記變量賦值的語句,替代以恰當(dāng)?shù)腷reak語句或continue語句。
- 每次替換后,編譯并測試。
5 Replace Nested Conditional with Guard Clauses(以衛(wèi)語句取代嵌套條件表達(dá)式)
條件邏輯使人難以看清正常的執(zhí)行路徑。使用衛(wèi)語句表現(xiàn)所有你特殊情況。
Motivation:條件表達(dá)式一共有兩種形式:1.所有分支都屬于正常行為。2.條件表達(dá)式提供的答案中只有一種是正常行為,其他都不常見。如果分支都屬于正常行為,使用if-else挺好的;如果某個(gè)條件極其罕見,就應(yīng)該單獨(dú)檢查該條件,并在該條件為真時(shí)立即返回。這樣單獨(dú)的檢查常常被稱為“衛(wèi)語句”。衛(wèi)語句的精髓在于給一條分支以特別的重視。
- 對(duì)于每個(gè)檢查,放進(jìn)一個(gè)衛(wèi)語句。ps:衛(wèi)語句要么就從函數(shù)中返回,要不就拋出一個(gè)異常。
- 每次講條件檢查替換成衛(wèi)語句后,編譯并測試。
6 Replace Conditional with Polymorphism(以多態(tài)取代條件表達(dá)式)
有根據(jù)類型字段來選擇函數(shù)不同的函數(shù)行為。將這個(gè)條件表達(dá)式的每個(gè)分支放進(jìn)一個(gè)子類內(nèi)的覆寫函數(shù)中,然后將原始函數(shù)聲明為抽象函數(shù)。
Motivation:使用條件表達(dá)式,使用的是硬編碼,很難對(duì)條件表達(dá)式進(jìn)行變化。
做法:
在做這個(gè)重構(gòu)首發(fā)之前,必須得有繼承結(jié)構(gòu),這種繼承結(jié)構(gòu)有兩種手段去建立:Replace Type Code with Subclasses 和 Replace Type Code with State/Strategy。
- 如果要處理的條件表達(dá)式是一個(gè)更大函數(shù)中的一部分,首先對(duì)條件表達(dá)式進(jìn)行分析,然后使用extract Method把它提煉到一個(gè)獨(dú)立函數(shù)中。
- 如果有必要,使用Move Method將條件表達(dá)式放置到繼承結(jié)構(gòu)的頂端。
- 任選一個(gè)子類,在其中建立一個(gè)函數(shù),使之覆寫超類中容納條件表達(dá)式的那個(gè)函數(shù)。將與該子類先關(guān)的條件表達(dá)式分支賦值到新建函數(shù)中,并對(duì)它進(jìn)行適當(dāng)調(diào)整。
- 編譯,測試。
- 在超類刪除到表達(dá)式內(nèi)被賦值的分支。
- 編譯,測試。
- 重復(fù)上述的過程,知道所有分支都被移動(dòng)到子類內(nèi)。
- 將超類之中容納條件表達(dá)式的函數(shù)聲明為抽象函數(shù)。
7 Introduce Null Object(引入Null對(duì)象)
你需要再三檢查某對(duì)象是否為null。將null值替換為null對(duì)象。
Motivation:這是踐行多態(tài)的一個(gè)非常好的方案。試想,如果對(duì)每個(gè)對(duì)象,都必須判斷其是否為null,然后才能進(jìn)行下一步的行為。那么系統(tǒng)中一定會(huì)運(yùn)行大量的判斷代碼,這是就大量的重復(fù)代碼。
做法:
- 為源類建立一個(gè)子類,使其行為就像源類的null版本。在源類和null子類中都加上isNull(),前者返回false,后者返回true。
- 編譯。
- 找出所有索求源對(duì)象卻獲得一個(gè)null的地方。修改這些地方,使它們調(diào)用isNull()函數(shù)。
- 編譯,測試。
- 找出這樣的程序點(diǎn):如果對(duì)象不是null,做A動(dòng)作,否則B動(dòng)作。
- 對(duì)于每一個(gè)上述弟弟昂,在null類中覆蓋A動(dòng)作,使其行為和B相同。
- 使用上述被覆寫的動(dòng)作,然后刪除對(duì)象是否為null的條件測試。編譯并測試。
tips:其實(shí)這樣的方式可以被認(rèn)為是特例類模式,用特例來減少處理特例的開銷。
8 Introduce Assertion
用斷言明確表明對(duì)程序狀態(tài)的假設(shè)。
Motivation:可以幫助我們理解某些條件對(duì)程序是極其重要的。斷言可以幫助程序閱讀者閱讀代碼,可以幫助調(diào)試程序。
做法:
只要程序源不犯錯(cuò),斷言就應(yīng)該不會(huì)對(duì)系統(tǒng)運(yùn)行造成任何影響,所以加入斷言永遠(yuǎn)不會(huì)影響程序的行為。斷言一定要用來判斷一定為真的條件。