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?