Есть ли причина не использовать Optional в качестве аргумента метода в том случае, если вы знаете, что аргумент является чем-то, что может или не может быть необходимо?

11

С Java 8 я видел все больше и больше статей об использовании Option / Optional. Я понимаю, что они пытаются изобразить, и вижу много примеров того, как они используются в качестве возвратов. Однако я не вижу, чтобы они использовались в качестве аргументов метода / функции в языках, в которых нет синтаксиса для параметров по умолчанию / необязательных.

Есть ли причина не использовать Optionalв качестве аргумента метода в том случае, если вы знаете, что аргумент - это то, что может или не может быть необходимо? Вот пример, который я мог придумать:

Optional<Customer> lookupCustomer(String firstName, Optional<String> middleName, String lastName)
Николас
источник
Это обычное использование для них в Haskell, который также не имеет аргументов по умолчанию (карри боль).
Даниэль Гратцер
Смотрите мой ответ на связанный вопрос переполнения стека. Вкратце, Optionalпредназначен в первую очередь для возвращаемых значений, которые могут отсутствовать. Конечно, возможны и другие варианты, но они громоздки и, вероятно, имеют плохой стиль.
Стюарт Маркс

Ответы:

6

Одной из причин является то , что концептуально firstName, middleNameи lastNameлогически один аргумент, а не три. Они все части большего целого, и можно представить, что они почти всегда проходят вместе. В функциональных языках они, вероятно, будут переданы как кортеж или запись; В Java их нет, поэтому они, вероятно, будут объединены в класс Name. Обратите внимание, что если вам нужно составить функции, которые принимают и возвращают полные имена, вы не сможете без их агрегирования - в конце концов, вы можете вернуть только одно значение.

Может быть, это не очень часто приходит к выводу, что значение является необязательным и также не является частью большего целого. Если функция требует определенного значения для выполнения своей работы, то эта функция не должна принимать Optional. Если вам нужно объединить в цепочку операции, которые могут не возвращать значение, прервать, Nothingесли какая-либо функция в процессе выполнения потерпит неудачу, вы можете выполнить цепочку вызовов flatMap, а если вы хотите завершить работу с исключением, вы можете использовать его get()на любом этапе пути или на конец цепи.

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

Я не думаю, что это так сильно, что это неправильно, так как это довольно необычный вариант использования.

Doval
источник
5

Существует не так много языков, которые не поддерживают аргументы по умолчанию, поэтому это не распространенное использование. Я лично думаю, что ваше использование не так уж страшно, но это не будет идиоматическая Java. Java намеренно не имеет аргументов по умолчанию, чтобы вместо этого использовать принудительную перегрузку, которая имеет преимущество в том, что компилятор проверяет ваши аргументы вместо того, чтобы требовать ifоператоров внутри функции.

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

Карл Билефельдт
источник