Статьи

Исправление, если запах

Время от времени у нас могут появиться огромные операторы if в нашей кодовой базе. Эти операторы должны быть сохранены и менять один и тот же блок кода снова и снова. Это распространено также в случаях, когда оператор if проверяет, принадлежит ли переменная определенному диапазону значений.

Предположим, у вас есть перечисление

01
02
03
04
05
06
07
08
09
10
public enum FoodType {
 
    FRUIT,
    VEGETABLES,
    RED_MEAT,
    WHITE_MEAT,
    FISH,
    DIARY,
    CERIAL
}

И у вас есть функция, дающая некоторые рекомендации

01
02
03
04
05
06
07
08
09
10
11
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 в функцию.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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 изменится на это.

01
02
03
04
05
06
07
08
09
10
11
public String recommend(FoodType foodType) {
 
        if(DietFilter.proteinBased(foodType)) {
 
            //execute a procedure
        } else if(DietFilter.fiberBased(foodType)) {
            //execute a procedure
        } else {
            //execute a procedure
        }
    }

Если в перечисление добавлено больше типов продуктов питания, разработчик должен будет только изменить конструкцию набора и добавить дополнительный тип продуктов питания.
Это будет намного проще, чем изменение нескольких частей кода, и это будет более читабельным.

Опубликовано на Java Code Geeks с разрешения Эммануила Гкациоураса, партнера нашей программы JCG. Смотрите оригинальную статью здесь: Исправление, если запах

Мнения, высказанные участниками Java Code Geeks, являются их собственными.