Перегрузка метода Java

#java

#java

Вопрос:

У меня есть 2 альтернативы для реализации метода вычисления, и мне интересно, какой подход был бы лучшим.

Методу требуются некоторые параметры int и double и (в некоторых случаях) специальный флаг для выполнения некоторых других вычислений.

В первом примере я мог бы вызвать метод с помощью ‘calculateFoo (1, 2.0d)’, чтобы иметь логический флаг == FALSE.

Во втором примере я всегда должен устанавливать логический флаг (даже если он мне не нужен)

Метод 1: (здесь я использую ‘…’ в качестве параметра ‘перегрузки метода’)

 public SomeObject calculateFoo(int pIntValue, double pDoubleValue, boolean... pDoSpecialStuff) {

    if (pDoSpecialStuff.length == 0 || pDoSpecialStuff[0] == false) {
        // method was called without boolean flag or boolean flag was set to FALSE

        // do some calculation stuff
        // ...
    } else {
        // method was called with boolean flag == TRUE

        // do some other calculation stuff
        // ...
    }

    return SomeObject; 
}
  

Метод 2: (это «общий» подход)

 public SomeObject calculateFoo(int pIntValue, double pDoubleValue, boolean pDoSpecialStuff) {

    if (pDoSpecialStuff == false) {
        // method was called with boolean flag == FALSE

        // do some calculation stuff
        // ...
    } else {
        // method was called with boolean flag == TRUE

        // do some other calculation stuff
        // ...
    }

    return SomeObject; 
}
  

Комментарии:

1. Вместо использования флагов для определения «что делать» у вас должно быть несколько методов — один метод — одно действие. Это объектно-ориентированный подход. Флаги, как правило, уродливы.

Ответ №1:

оба ваших метода пахнут кодом, логические флаги отстой

вот мое предложение

 public SomeObject calculateFoo(int pIntValue, double pDoubleValue) {
    // normal calculation here 
}

public SomeObject calculateFooSpecial(int pIntValue, double pDoubleValue) {
    // special calculation here 
}
  

Комментарии:

1. 1, и оба метода могут вызывать третий, частный метод, который содержит код, общий для обоих вычислений

Ответ №2:

Рассмотрим следующий шаблон:

 public ResultType calcFoo( int i, double d ) {
    return calc( i, d, false );
}

public ResultType calcFoo( int i, double d, boolean flag ) {
    if( flag ) {
        ...
        return resu<
    }
    else {
        ...
        return resu<
    }
}
  

Обычно лучше использовать enum вместо логического флага. Это делает ваш код более читаемым и таким же быстрым.

Я заметил, что вы рассматривали возможность использования varargs. Если вы хотите использовать больше флагов, рассмотрите возможность использования EnumSet для передачи набора флагов методу. Если вы хотите передать флаги 0 или 1, varargs еще более определенно является антипаттером.

Ответ №3:

Сделайте второй вариант, поскольку он более явный. Переменные значения позволят вам передавать более одного логического значения, которые затем не используются. Лучше явно определить интерфейс, используя одно логическое значение.

Если вы хотите иметь значение по умолчанию для логического флага, используйте другую перегрузку:

 public SomeObject calculateFoo(int pIntValue, double pDoubleValue) {
   return calculateFoo(pIntValue, pDoubleValue, false);
}
  

Ответ №4:

Я бы определил еще один метод с двумя параметрами для выполнения вычисления по умолчанию.

 public SomeObject calcFoo(int, double) {
    ....
}

public SomeObject calcFoo(int i, double d, boolean b) {
    if(b) {
        ....
    } else {
        return calcFoo(i, d);
    }
}