Idomy z java 8 I
To nie będzie zamknięty cykl, bo wraz z czasem będę w niego wrzucać kolejne przykłady.
Na pierwszy ogień coś co przewija się w kodzie, który transformuje jedne obiekty w inne.
Listing 1. Klasyczny kod
class MyEntity{
private String name;
// gettery, settery, inne pola itp.
}
class MyOtherEntity{
private String name;
// gettery, settery, inne pola itp.
public MyOtherEntity(){}
public MyOtherEntity(MyEntity my){
this.name = my.name
//...
}
}
class Converter{
public MyOtherEntity convert(MyEntity my){
if(my != null )
return new MyOtherEntity(my);
return new MyOtherEntity();
}
}
Kod ten przedstawia problem z dokładnością do if-a, który może być przeniesiony do konstruktora MyOtherEntity(MyEntity). Kod zdaje się być prosty, ale tylko dlatego, że mamy tu tylko jedno pole. Przy większej liczbie pól zaczyna być nieciekawie. Rozwiązanie, a w zasadzie uproszczenie zapisu:
Listing 2. Kod z „podwójnym new”
class Converter{
public MyOtherEntity convert(MyEntity my){
return Optional.ofNullable(my)
.map(MyOtherEntity::new)
.orElseGet(MyOtherEntity::new);
}
}
Co tu się dzieje? Najpierw tworzymy Optional, który pozwala na wykonanie map wtedy, gdy my nie jest null. Jako transformatę przekazujemy konstruktor. Który? Ponieważ kompilator oczekuje w tym miejscu czegoś co przyjmie jako parametr MyEntity i jest w stanie odnaleźć odpowiedni konstruktor. Jeżeli jednak my jest null to zostanie wywołany Supplier z orElseGet. I znowuż jako parametr jest przekazany konstruktor, ale tym razem kompilator będzie oczekiwał czegoś bezparametrowego.
Podsumowując. Zamieniliśmy „ifologię” na kod oparty o dobór odpowiednich typów, tu dokładnie wnioskowanie konstruktora, co pozwala na przerzucenie części odpowiedzialności na kompilator. Zadanie dla was – jak zmieniły się testy konwertera.