Lombok, czyli annotation driven development – zyski i zagrożenia

sages.pl 3 lat temu
Pisząc kod w javie i tworząc nowe klasy, często potrzebujemy napisać metody, które są praktycznie prawie takie same dla różnych klas. Na przykład, mając:

```
public class User {
private String username;
private String email;
}
```

Czyli zwykłą małą klasę trzymającą dane o użytkowniku, prawdopodobnie będziemy potrzebować utworzyć:

* konstruktory (domyślny i z parametrami)
* gettery i settery
* equals i hashcode
* toString

Zatem, nasza mała klasa rozrasta się z kilku linii do aż 60 (na rzecz czytelności artykułu, pominę wygenerowany przez IDE kod). Pomimo rozrostu, nie dodaliśmy **żadnej** logiki biznesowej. Nic to nie wniosło. Taki kod nazywamy *boilerplate code* – czyli kod, który nic nam nie wnosi, ale jest potrzebny do napisania, żeby aplikacja działała.

### Lombok

Z pomocą przychodzi nam biblioteka **lombok**, która generuje owy boilerplate code na podstawie użytych adnotacji. Żeby zacząć korzystać z lomboka, dodajemy jego zależność:

```

org.projectlombok
lombok

```

Jeśli nie korzystamy ze Spring Boota, potrzebne nam będzie również dodanie wersji. Ekwiwalent 60 linijkowej klasy możemy zapisać teraz z pomocą kilku samowyjaśniających się adnotacji:

```
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@EqualsAndHashCode
@ToString
public class User {
private String username;
private String email;
}
```

Jak widać, zaoszczędziliśmy wiele linijek kodu. Poszliśmy w stronę programowania *deklaratywnego* – mówimy, **co** chcemy mieć zrobione (używając adnotacji), a nie **jak** to ma być zrobione.

Przybyło jednak adnotacji – możemy użyć choćby „pewnego zbioru” adnotacji, jak np na poniższym przykładzie:

```
@AllArgsConstructor
@NoArgsConstructor
@Data
public class User {
private String username;
private String email;
}
```

*@Data* zawiera w sobie *@Getter*, *@Setter*, *@RequiredArgsConstructor*, *@ToString* oraz *@EqualsAndHashCode*.

Również przydatną rzeczą jest *@Builder* – dzięki temu, będziemy mieć dostarczony builder pattern przy tworzeniu obiektów danej klasy.

### Lombok – wady

*No dobrze, nie mamy boilerplate kodu – czy są zatem jakieś wady?*

Pierwszą, o której się pomyśli, to brak możliwości debugowania – nie postawisz breakpointa na adnotacji i nie zobaczysz parametrów metody. Okej – można wykonac proces tzw. *delombok*, i postawić breakpointa w wygenerowanym kodzie, ale wtedy cała zabawa zaczyna tracić sens.
Mając zbiór adnotacji (potocznie, pejoratywnie, można to nazwać *annotation driven development*) łatwo pogubić się w tym gąszczu – np mając tak oznaczoną klasę:

```
@Data
@Value
public class User {
private final String username;
private final String email;
}
```

Nie od razu widzimy, które metody są wygenerowane, a które nie. Dopiero później możemy się przekonać, iż *@Value* zawiera w sobie *@AllArgsConstructor*, *@Data* zawiera w sobie *@RequiredArgsConstructor*, natomiast w tym wszystkim brakuje nam... *@NoArgsConstructor*, czyli konstruktora domyślnego. Jaki może być tego skutek? Niektóre biblioteki do serializacji / deserializacji, jak np Jackson, wymagają konstruktora domyślnego – w przeciwnym wypadku, na konstruktor z parametrami należy nanieść stosowną adnotację. Niestety, wyjdzie to dopiero w runtimie...

### Podsumowanie

Jak widać, stosowanie lomboka pozwala znacząco zredukować boilerplate code i tym samym przyspieszyć proces wytwarzania systemu oraz zwiększyć czytelność kodu. Jednak nie zapominajmy o rozsądku, żeby pewnego dnia nie znaleźć się w gąszczu samych adnotacji, ponieważ w przypadku jakiegoś błędu, namierzenie jego przyczyny jest dużo trudniejsze.
Idź do oryginalnego materiału