Czy jest jakiś powód, aby nie używać Opcjonalnego jako argumentu metody w przypadku, gdy wiadomo, że argument jest potrzebny lub nie?

11

W Javie 8 widziałem coraz więcej artykułów na temat korzystania z Option / Optional. Rozumiem, co próbują przedstawić, i widzę wiele przykładów ich wykorzystania jako zwrotów. Jednak nie widzę ich jako argumentów metody / funkcji w językach, które nie mają składni parametrów domyślnych / opcjonalnych.

Czy istnieje jakikolwiek powód, aby nie używać Optionaljako argumentu metody w przypadku, gdy wiadomo, że argument jest czymś, co może lub nie być potrzebne? Oto przykład, o którym mógłbym pomyśleć:

Optional<Customer> lookupCustomer(String firstName, Optional<String> middleName, String lastName)
Mikołaj
źródło
Jest to powszechne zastosowanie dla nich w Haskell, który również nie ma domyślnych argumentów (curry pain).
Daniel Gratzer
Zobacz moją odpowiedź na powiązane pytanie dotyczące przepełnienia stosu. W skrócie, Optionaljest przeznaczony przede wszystkim do zwracanych wartości, które mogą być nieobecne. Oczywiście możliwe są inne zastosowania, ale są nieporęczne i prawdopodobnie mają kiepski styl.
Stuart Marks

Odpowiedzi:

6

Jednym z powodów jest to, że pod względem koncepcyjnym, firstName, middleName, i lastNamesą logicznie jednym argumentem, a nie trzy. Wszystkie są częścią większej całości i można sobie wyobrazić, że prawie zawsze są one przekazywane razem. W językach funkcjonalnych byłyby prawdopodobnie przekazywane jako krotka lub rekord; Java nie ma ich, więc prawdopodobnie zostałyby połączone w klasę Name. Zauważ, że gdybyś musiał skomponować funkcje, które przyjmują i zwracają pełne nazwy, nie byłoby to możliwe bez ich agregacji - w końcu możesz zwrócić tylko jedną wartość.

Może po prostu nie pojawia się zbyt często, że wartość jest opcjonalna, a także nie stanowi części większej całości. Jeśli funkcja wymaga pewnej wartości do wykonania swojej pracy, to funkcja ta nie powinna akceptować Optional. Jeśli potrzebujesz połączyć łańcuch operacji, które mogą nie zwrócić wartości, przerwać, Nothingjeśli jakaś funkcja po drodze się nie powiedzie, możesz połączyć wywołania flatMap, a jeśli chcesz zawieść z wyjątkiem, możesz użyć get()na dowolnym etapie lub koniec łańcucha.

Jeśli wartość jest naprawdę opcjonalna, a funkcja wykonuje dwie różne rzeczy w zależności od jej obecności lub nieobecności, jest to zapach kodu, chyba że jest to opakowanie dwóch mniejszych funkcji, które wykonują jedną rzecz, a ta szczególna kombinacja decyzji jest bardzo powszechna.

Nie sądzę, aby było tak bardzo, że jest źle, ponieważ jest to stosunkowo rzadki przypadek użycia.

Doval
źródło
5

Nie ma zbyt wielu języków, które nie obsługują domyślnych argumentów, więc nie jest to powszechne użycie. Osobiście uważam, że twoje użycie nie jest straszne, ale nie będzie to idiomatyczna Java. Java bardzo celowo nie ma domyślnych argumentów, aby zamiast tego wymusić użycie przeciążenia, co ma tę zaletę, że kompilator sprawdza argumenty zamiast wymagać ifinstrukcji wewnątrz funkcji.

Innymi słowy, stworzysz dwie różne wersje zapytania: jedną o drugim nazwisku i drugą bez. Jeśli możesz to zrobić w zwięzły sposób, dobrym pomysłem jest użycie opcji. Jeśli jest wystarczająco gadatliwy, byś chciał go w dwóch osobnych funkcjach, równie dobrze możesz użyć przeciążenia i uczynić go idiomatycznym.

Karl Bielefeldt
źródło