Я читал на многих веб-сайтах Необязательный должен использоваться только как тип возвращаемого значения и не использоваться в аргументах метода. Я изо всех сил пытаюсь найти логическую причину. Например, у меня есть часть логики, которая имеет 2 необязательных параметра. Поэтому я думаю, что было бы целесообразно написать мою подпись метода как это (решение 1):
public int calculateSomething(Optional<String> p1, Optional<BigDecimal> p2 {
// my logic
}
Многие параметры веб-страниц Необязательно не следует использовать в качестве аргументов метода. Имея это в виду, я мог бы использовать следующую сигнатуру метода и добавить ясный комментарий Javadoc, чтобы указать, что аргументы могут быть нулевыми, надеясь, что будущие сопровождающие будут читать Javadoc и поэтому всегда выполняют нулевые проверки до использования аргументов (решение 2)
public int calculateSomething(String p1, BigDecimal p2) {
// my logic
}
В качестве альтернативы я мог бы заменить мой метод четырьмя общедоступными методами, чтобы обеспечить более удобный интерфейс и сделать его более очевидным. p1 и p2 являются необязательными (решение 3):
public int calculateSomething() {
calculateSomething(null, null);
}
public int calculateSomething(String p1) {
calculateSomething(p1, null);
}
public int calculateSomething(BigDecimal p2) {
calculateSomething(null, p2);
}
public int calculateSomething(String p1, BigDecimal p2) {
// my logic
}
Теперь я попробую написать код класса, который вызывает этот кусок логики для каждого подхода. Сначала я извлекаю два входных параметра из другого объекта, который возвращает Optional
, а затем вызываю calculateSomething
. Поэтому, если используется решение 1, вызывающий код будет выглядеть так:
Optional<String> p1 = otherObject.getP1();
Optional<BigInteger> p2 = otherObject.getP2();
int result = myObject.calculateSomething(p1, p2);
если используется решение 2, вызывающий код будет выглядеть так:
Optional<String> p1 = otherObject.getP1();
Optional<BigInteger> p2 = otherObject.getP2();
int result = myObject.calculateSomething(p1.orElse(null), p2.orElse(null));
если применяется решение 3, я мог бы использовать вышеприведенный код, или я мог бы использовать следующее (но это значительно больше кода):
Optional<String> p1 = otherObject.getP1();
Optional<BigInteger> p2 = otherObject.getP2();
int result;
if (p1.isPresent()) {
if (p2.isPresent()) {
result = myObject.calculateSomething(p1, p2);
} else {
result = myObject.calculateSomething(p1);
}
} else {
if (p2.isPresent()) {
result = myObject.calculateSomething(p2);
} else {
result = myObject.calculateSomething();
}
}
Итак, мой вопрос: почему считается неправильной практикой использовать Optional
как аргументы метода (см. решение 1)?. Это выглядит как наиболее читаемое решение для меня и делает наиболее очевидным, что параметры могут быть пустыми/нулевыми для будущих сопровождающих. (Я знаю, что дизайнеры Optional
предполагали, что он будет использоваться только как возвращаемый тип, но я не могу найти никаких логических причин не использовать его в этом сценарии).