第9章 簡化條件表示式
簡介:
這章主要是講解了怎樣簡化程式中的條件表示式,簡化程式碼邏輯。
分解條件表示式(Decompose Conditional)
1.理解:
你有一個複雜的條件(if-then-else)語句,可以從if,then,else三個段落中分別提煉獨立函式。
2.動機:
越來越多複雜的條件表示式,會增加閱讀程式碼的難度。所以分解,提煉成多個獨立函式是很有必要的。提煉出的函式根據每個小塊程式碼用途來命名,清楚表達自己的意圖。
3.做法:
類似“以查詢替代臨時變數”的方式,這裡是以查詢替代表達式。
合併條件表示式(Consolidate Conditional Expression)
1.概念:
你有一系列條件測試,都得到相同的結果。將這些測試合併為一個條件表示式,並將這個條件表示式提煉成為一個獨立函式。
//合併前 double disabilityAmount() { if (seniority < 2) return 0; if (monthsDisabled > 12) return 0; if (isPartTime) return 0; } //合併後 double disabilityAmount { if (isNotEligableForDisability()) return 0; }
2.做法:
先將這些能合併的表示式合併,到底用提煉函式將它們提取到一個函式裡,還是用一個完整表示式直接顯示出來,視情況而定。
合併重複的條件片段(Consolidate Duplicate Conditional Fragments)
1.概念:
很好理解,顧名思義。
//合併前 if (isSpecialDeal()) { total = price * 0.95; send(); } else { total = price * 0.98; send(); } //合併後 if (isSpecialDeal()) { total = price * 0.95; } else { total = price * 0.98; } send();
移除控制標記(Remove Control Flag)
1.概念:
在一系列布林表示式中,某個變數帶有“控制標記”的作用,則以break語句或者return語句取代控制標記。
2.動機:
移除控制標記會使條件語句的用途更加清晰。
3.例子:
//改變前 public class ControlMark { public void checkSecurity(String[] people) { boolean found = false; for (int i = 0; i < people.length; i++) { if (!found) { if (people[i].equalsIgnoreCase("Don")) { //do something found = true; } if (people[i].equalsIgnoreCase("John")) { //do something found = true; } } } } //改變後 public String checkSecurityAfer(String[] people) { for (int i = 0; i < people.length; i++) { if (people[i].equalsIgnoreCase("Don")) { //do something return "Don"; } if (people[i].equalsIgnoreCase("John")) { //do something return "John"; } } return " "; } }
以衛語句取代巢狀條件表示式(Replace Nested Conditional with Guard Clauses)
1.什麼是衛語句:
衛語句就是把複雜的條件表示式拆分成多個條件表示式,比如一個很複雜的表示式,嵌套了好幾層的if - then-else語句,轉換為多個if語句,實現它的邏輯,這多條的if語句就是衛語句。
2.概念:函式中的條件邏輯使人難以看清正常的執行路徑,使用衛語句表現所有特殊情況。
//改變前 public class ComplicatedClauses { public void soulStandard() { String soulmate = ""; if ("boy".equalsIgnoreCase(soulmate)) { //not accept; } else if ("bad temperature".equalsIgnoreCase(soulmate)){ //not accept; } else { if ("beauty".equalsIgnoreCase(soulmate)) { if ("nice smile".equalsIgnoreCase(soulmate)) { //accept } else { //not accept } } } } } //使用衛語句,改變後 public class ComplicatedClauses { public void soulStandard() { String soulmate = ""; if ("boy".equalsIgnoreCase(soulmate)) { //not accept } if ("bad temperature".equalsIgnoreCase(soulmate)) { //not accept } if ("beauty".equalsIgnoreCase(soulmate) && "nice smile".equalsIgnoreCase(soulmate)) { //accept } else { //not accept } } }
3.動機:
條件表示式通常有兩種表達形式:
(1)所有分支都屬於正常行為,用if...else...語句。
(2)條件表示式提供的答案中只有一種是正常行為,其他都是不常見的,用衛語句。
→其實“以衛語句取代巢狀條件表示式”方法的精髓就是,給某條分支以特別的重視,如果它真的發生了,請做一些必要整理工作,然後退出。if...then...else各分支的重視程度是相等的。
4.注意:
在以衛語句表達時,可以考慮將條件反轉
//原式 if (result > 0) { .... } //改為 if (result <= 0) return result;
以多型取代條件表示式(Replace Conditional with Polymorphism)
1.概念:
你手上有個條件表示式,它根據物件型別的不同而選擇不同的行為。將這個條件表示式的每個分支放進一個子類的覆寫函式中,然後將原始函式宣告為抽象函式。
//原式
public double getSpeed() { switch (type) { case EUROPEAN: return getBaseSpeed(); case AFRICAN: return getBaseSpeed() - getLoadFactor() * numberOfCoconuts; case NORWEGIAN_BLUE: return (isNailed) ? 0 : getBaseSpeed(voltage); } throw new RuntimeException("Should be unreachable"); }
引入Null物件(Introduce Null Object)
1.概念:
你需要再三檢查某物件是否為null,將null值替換為null物件。
2.疑問:
將null替換為null物件,現在貌似沒有看到這麼做的了?
引入斷言(Introduce Assertion)
1.概念:
某一段程式碼需要對程式狀態做出某種假設。以斷言明確表現這種假設。
2.經驗:
目前經歷中一般在測試類加,其他情況視情況而定。