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.

2 myśli na temat “Idomy z java 8 I

  1. Zupełnie nie rozumiem jaki jest zysk w tym konkretnym przypadku. Mógłbyś podać przykład, który pokaże jak większa ilość pól skomplikuje metodę convert?

  2. Nieprecyzyjnie się wyraziłem. Chodzi o sytuację gdy konstruktor przyjmuje wiele parametrów 🙂 Wtedy zamiast ifologi można użyć sekwencji flatMap/map by uprościć kod.

Napisz odpowiedź

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax