vavrowy Option to jakiś żart?

0

Czy dostępny w bibliotece vavr.io Option to jakiś żart? Jaki jest sens optionala, który jest jak pole minowe i może na każdym kroku rzucić NPE?

Mamy powiedzmy takie proste struktury (jakiś przykład na szybko, niekoniecznie to mądre):

@Value
public class GroupOfPeople {
    Person leader;

    String name;
    int count;
    List<Person> people;
}
@Value
public class Person {
    PersonalDetails personalDetails;

    String name;
    String surname;
}
@Value
public class PersonalDetails {
    Address address;
}
@Value
public class Address {
    String country;

    String street;
    String buildingNum;
    String city;
}

No i chcemy sobie wyciągnąć z jakiego kraju jest lider grupy. Prosta sprawa w javowym optionalu.

String countryJava = Optional.ofNullable(group)
                .map(GroupOfPeople::getLeader)
                .map(Person::getPersonalDetails)
                .map(PersonalDetails::getAddress)
                .map(Address::getCountry)
                .orElse("Unknown country");

Natomiast analogiczny kod w vavrze będzie skutkował NullPointerException na każdym kroku. Gdy dowolna z operacji zwróci null to dostajeniemy NPE:

String countryVavr = Option.of(group)
                .map(GroupOfPeople::getLeader)
                .map(Person::getPersonalDetails)
                .map(PersonalDetails::getAddress)
                .map(Address::getCountry)
                .getOrElse("Unknown country");

Żeby temu zapobiec musimy dodać od cholery boilerplate'u, czyli dla każdej operacji map dodatkowo opakować w Optiona wynik:

String countryVavr1 = Option.of(group)
                .map(GroupOfPeople::getLeader)
                .flatMap(Option::of)
                .map(Person::getPersonalDetails)
                .flatMap(Option::of)
                .map(PersonalDetails::getAddress)
                .flatMap(Option::of)
                .map(Address::getCountry)
                .flatMap(Option::of)
                .getOrElse("Unknown country");

String countryVavr2 = Option.of(group)
                .flatMap(g -> Option.of(g.getLeader()))
                .flatMap(l -> Option.of(l.getPersonalDetails()))
                .flatMap(pd -> Option.of(pd.getAddress()))
                .flatMap(ad -> Option.of(ad.getCountry()))
                .getOrElse("Unknown country");

Czy ktoś używa tych vavrowych Optionów i nie boli go od tego głowa? Jaki jest sens optiona, który nie zabezpiecza zupełnie przed nullami?

7

To jest akurat zaleta. Nulle nie chowają się gdzieś po kątach tylko się wywalają. Twoje metody getLeader() itd. powinny zwracać Option.

1

Dokładnie podałeś jeden z 2 powodów dla którego nie używam Optionala z java.util.. Absurdalna implementacja map, które jest trochę jak map, a trochę jak flatMap. A @Michał Sikora już napisał co trzeba zrobić. Taka konstrukcja map w Optionalu powoduje, że jest mniejsza presja na wywalanie nulli z kodu, bo map trochę te nulle zamiast zamiata. Tyle, że przez to metody z nullami zostają w kodzie, a nie zawsze będą wywoływane wewnątrz map.
Generalnie zanim poznałem vavr i zacząłem używać tego Option, to ból głowy (tzw. zonk) robił mi czasem javawy Optional.

1 użytkowników online, w tym zalogowanych: 0, gości: 1