Я читав на багатьох веб-сайтах Необов’язково використовуватись лише як тип повернення, а не використовуватись у аргументах методів. Я намагаюся знайти логічну причину. Наприклад, у мене є логіка, яка має 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
s, а потім я викликаю 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
s в якості аргументів методу (див. Рішення 1)? Це виглядає як найбільш читабельне рішення для мене і робить найбільш очевидним, що параметри можуть бути порожніми / недійсними для майбутніх обслуговуючих служб. (Мені відомо, що дизайнери Optional
задумали його використовувати лише як тип повернення, але я не можу знайти жодних логічних причин не використовувати його у цьому сценарії).
null
?