1. 程式人生 > 實用技巧 >第9章 簡化條件表示式

第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.經驗:

目前經歷中一般在測試類加,其他情況視情況而定。