用 set或map修復if-else的壞味道 - egkatzioura

banq發表於2021-11-07

有時,我們的程式碼庫中可能會出現一些巨大的“if”語句。必須維護這些語句並一遍又一遍地更改相同的程式碼塊。這在“if”語句檢查變數是否屬於某個值範圍的情況下也很常見。
假設你有一個列舉:

public enum FoodType {
 
    FRUIT,
    VEGETABLES,
    RED_MEAT,
    WHITE_MEAT,
    FISH,
    DIARY,
    CERIAL
}

public String recommend(FoodType foodType) {
 
    if(foodType==FoodType.FISH||foodType==FoodType.RED_MEAT||foodType==FoodType.WHITE_MEAT) {
 
        //execute a procedure
    } else if(foodType==FoodType.FRUIT||foodType==FoodType.VEGETABLES) {
        //execute a procedure
    } else {
        //execute a procedure
    }
}


上面程式碼中:魚、紅肉和白肉適合喜歡蛋白質飲食的使用者,而水果和蔬菜更適合以纖維為基礎的飲食。在未來的情況下,這個列舉可能會得到增強,並新增更多的食物型別。'if' 程式碼塊將不得不更改。此外,如果在其他檔案中使用了這個複雜的“if”語句,您將不得不更改每個檔案。您不僅會有一個巨大的 if 塊,而且還有一個必須在每個檔案上維護的塊,這可能容易出錯。
為了避免這種情況,您可以將 if 語句的內容更改為函式。

package com.gkatzioura;
 
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
 
import static com.gkatzioura.FoodType.*;
 
public class DietFilter {
 
    private static final Set FOODS_WITH_PROTEIN = Collections.unmodifiableSet(new HashSet(Arrays.asList(
            FISH,
            RED_MEAT,
            WHITE_MEAT)));
 
    private static final Set FOODS_WITH_FIBER = Collections.unmodifiableSet(new HashSet(Arrays.asList(
            FRUIT,
            VEGETABLES)));
 
    public static boolean proteinBased(FoodType foodType) {
        return FOODS_WITH_PROTEIN.contains(foodType);
    }
 
    public static boolean fiberBased(FoodType foodType) {
        return FOODS_WITH_FIBER.contains(foodType);
    }
 
}


因此,我們沒有新增食物型別的每個單個案例,而是在“if”語句中建立了一個函式,該函式檢查給定的引數是否屬於特定組。
因此,您的“if”語句將更改為此。

public String recommend(FoodType foodType) {
 
    if(DietFilter.proteinBased(foodType)) {
 
        //execute a procedure
    } else if(DietFilter.fiberBased(foodType)) {
        //execute a procedure
    } else {
        //execute a procedure
    }
}


如果將更多食物型別新增到列舉中,開發人員只需更改集合的構造並新增額外的食物型別。這比更改程式碼的多個部分要容易得多,而且更具可讀性。
 

相關文章