Java: как заменить несколько вложенных операторов if-else более понятным дизайном - PullRequest
0 голосов
/ 25 сентября 2019

Мне нужно выполнить другое действие doAction1(), doAction2() ... в зависимости от значения и / или типа некоторых переменных и возвращаемого значения некоторых функций.Все комбинации могут быть возможны, в принципе.

Быстрое решение состоит в том, чтобы протестировать все комбинации внутри вложенных операторов if-else, но полученный код довольно уродлив и его сложно поддерживать и расширять (например, у меня есть новыйусловия для проверки).Ниже приведен пример кода.Я использую Java SE 8:

public static boolean myFunct () {
    return true;  // hardcoded, it could also return false
}

public static void main(String[] args) {

    int x = 1;  // hardcoded, it could also be =2
    Object o = new String();  // hardcoded, it could also be an Integer

    // here I begin to test to decide which action to execute
    if (x == 1) {
        if (o instanceof String) {
            if ( myFunct() ) {
                // do this if x==1 AND o is a String AND myFunct() returns true
                doAction1();  
            }
            else {
                doAction2();
            }
        }
        else if (o instanceof Integer) {
            if ( myFunct() ) {
                doAction3();
            }
            else {
                doAction4();
            }
        }
    }
    else if (x == 2) {
        if (o instanceof String) {
            if ( myFunct() ) {
                doAction5();
            }
            else {
                doAction6();
            }
        }
        else if (o instanceof Integer) {
            if ( myFunct() ) {
                doAction7();
            }
            else {
                doAction8();
            }
        }
    }
}

private static void doAction8() {
    // do some work...
}

private static void doAction7() {
    // do some work...
}

private static void doAction6() {
    // do some work...
}

private static void doAction5() {
    // do some work...
}

private static void doAction4() {
    // do some work...
}

private static void doAction3() {
    // do some work...
}

private static void doAction2() {
    // do some work...
}

private static void doAction1() {
    // do some work...
}

. Я читал о шаблоне проектирования RuleEngine, который может элегантно применяться к подобным случаям и заменяет вложенные операторы if-else, но не могу найти, как реализовать его для моегоcase.

Заранее благодарим за рекомендации.

1 Ответ

0 голосов
/ 26 сентября 2019

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

  • Сначала вычислите ключ (индекс) на основе оценок условий.

Например,

|---------------|---------------|---------------|---------------|
|   condition1  |   condition2  |   condition3  |      key      |
|---------------|---------------|---------------|---------------|
|     true      |     true      |     true      |      111      |
|...............|...............|...............|...............|
|     true      |     true      |     false     |      110      |
|...............|...............|...............|...............|
|     true      |     false     |     false     |      100      |
|...............|...............|...............|...............|
|     true      |     false     |     true      |      101      |
|...............|...............|...............|...............|
|     false     |     true      |     true      |      011      |
|...............|...............|...............|...............|
|     false     |     true      |     false     |      010      |
|...............|...............|...............|...............|
|     false     |     false     |     false     |      000      |
|...............|...............|...............|...............|
|     false     |     false     |     true      |      001      |
|---------------|---------------|---------------|---------------|

Если для вашего случая используется строковый ключ,

String methodIndex = "";
methodIndex += (x == 1) ? "1" : "0";
methodIndex += (o instanceof String) ? "1" : "0";
methodIndex += (myFunct()) ? "1" : "0";

Возможно побитовые операции могутбыть использованы для более эффективной работы, если существуют только истинно-ложные условия.Иначе, если у вас есть многозначные условия (например, x может быть 1, 2, 3 ...), вычисление клавиши String будет проще.

  • Затем, основываясь на вычисленном ключе, вызовите правильное действие (возможно, используя оператор switch.
switch (methodIndex) {
    case "111":
        doAction1();
        break;
    case "110":
        doAction2();
        break;
    case "101":
        doAction3();
        break;
    case "100":
        doAction4();
        break;
    case "011":
        doAction5();
        break;
    case "010":
        doAction6();
        break;
    case "001":
        doAction7();
        break;
    case "000":
        doAction8();
        break;
    default:
        System.out.println("No action defined");
}
...