Praktyczna Java. Lombok — boilerplate generator

By 31 October 2015 Praktyczna Java

hash­Code, equals, toString, log­gery, get­tery, set­tery — kod, który niby inc nie robi, a jest potrzeb­ny. Do tego może przys­porzyć nam niemało prob­lemów. A co byś powiedzi­ała na to, żeby zastąpić go jed­ną adno­tacją? Uwa­ga: po przeczy­ta­niu tego wpisu nie będziesz chci­ała pra­cow­ać w pro­jek­tach bez Lombok’a ;)

Boilerplate

Być może spotkałaś się już z tym ter­minem, ogól­nie oznacza on kod, który nie real­izu­je żad­nej funkcji biz­ne­sowej, a jedynie służy połącze­niu ele­men­tów w całoś­ci, udostęp­nie­niu jakichś danych, logowa­niu infor­ma­cji itp — inny­mi słowy jest niezbęd­ny, ale pow­tarzal­ny, nieciekawy do pisa­nia i ‘zaśmieca­ją­cy’ kod aplikacji.

Tem­inem tym określamy wszys­tkie metody takie jak get­tery, set­tery, toString, hash­Code oraz equals a także deklarac­je log­gerów i podob­ne. Wprawdzie wiele IDE pozwala nam gen­erować ten kod automaty­cznie, to nadal musimy o nim pamię­tać oraz ‘zaśmieca’ nam on resztę aplikacji.

Lombok

W odpowiedzi na te prob­le­my pow­stał Lom­bok — sto­sunkowo niewiel­ka bib­liote­ka, która daje nam kil­ka adno­tacji pozwala­ją­cych na gen­erowanie tego typu kodu automatycznie.

Co wyróż­nia Lom­bok na tle innych narzędzi? O ile wcześniejsze rozwiąza­nia opier­ały się o gen­eryczny kod, najczęś­ciej korzys­ta­ją­cy z reflek­sji w cza­sie dzi­ała­nia pro­gra­mu, Lom­bok po pros­tu ‘dopisu­je’ kod do aplikacji w cza­sie jej kom­pi­lacji. Dzię­ki temu nie tracimy na wyda­jnoś­ci, a jed­nocześnie hon­oru­je on wszys­tkie ‘nad­pisane’ przez nas metody, dzię­ki czemu inte­gru­je się w sposób nieinwazyjny.

Co ciekawe, wyko­rzys­tu­je ona nieu­doku­men­towaną funkcjon­al­ność kom­pi­la­to­ry Javy — o ile po szczegóły zain­tere­sowanych odsyłam do lit­er­atu­ry (mówimy tutaj o mody­fikacji AST), ogól­nie chodzi o to, że w momen­cie kiedy Java ‘czy­ta’ kod przed kom­pi­lacją i zamienia go na reprezen­tację w pamię­ci, Lom­bok mody­fiku­je tą reprezen­tację doda­jąc odpowied­nie metody i pola. Dzię­ki temu dla Javy dodane funkcjon­al­noś­ci wyglą­da­ją jak stan­dar­d­owy kod, a jed­nocześnie nie mamy dodatkowych ograniczeń związanych z koniecznoś­cią dziedz­iczenia po jakiejś klasie lub odwoły­wa­nia się do innych klas. Pon­ad­to Lom­bok jest wyma­gany tylko w momen­cie kom­pi­lacji i nie musi być obec­ny w skom­pi­lowanej aplikacji.

Instalacja i użycie

Korzys­tanie z Lom­bo­ka wyma­ga jedynie jego dołączenia do pro­jek­tu jako bib­liote­ki — jeśli uży­wamy Mave­na, wystar­czy sko­rzys­tać z poniższego fragmentu:

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.16.6</version>
    <scope>provided</scope>
</dependency>

Pozosta­je jeszcze jeden krok — ‘powiedze­nie’ nasze­mu IDE, aby widzi­ał także metody gen­erowane przez Lom­bo­ka. Na szczęś­cie sam project Lom­bok się tym zajmie w przy­pad­ku Eclipse — wystar­czy uru­chomić plik JAR i postępować wg wskazówek na ekranie. W przy­pad­ku Intel­liJ dostęp­ny jest plu­g­in, który może­my zain­stalować w stan­dar­d­owy sposób z poziomu IntelliJ.

Adnotacje

Lom­bok ofer­u­je funkcjon­al­ność za pośred­nictwem adno­tacji — zarówno na poziomie klas jak i metod. Poniżej zbiór najważniejszych, pełną doku­men­tację możesz znaleźć na stron­ie pro­jek­tu pod adresem https://projectlombok.org/features/index.html .

@Getter / @Setter

Adno­tac­je te pozwala­ją na dodanie get­terów lub set­terów dla wybranych pól. Adno­tac­ja umieszc­zona nad klasą spowodu­je dodanie metod dla wszys­t­kich pól tej klasy. Przykład­owe zastosowanie:

@Getter
@Setter
public class Aplikacja {
    @Setter(AccessLevel.PROTECTED) private String prywatnePole;
    private String publicznePole;
}

Powyższy kod utworzy pub­liczne get­tery i set­tery do obu pól, za wyjątkiem metody set­Pry­wat­nePole, która będzie miała widoczność protected.

@EqualsAndHashCode

Dzię­ki tej adno­tacji, wygen­erowane zostaną metody hash­Code oraz equals uwzględ­ni­a­jące wszys­tkie pola. Metody te oczy­wiś­cie speł­ni­a­ją kon­trakt hash­Code-equals, o którym pisal­iśmy więcej w osob­nym wpisie. Przykład­owe użycie:

@EqualsAndHashCode
public class Aplikacja {
    private String prywatnePole;
    private String publicznePole;
}

Powyższy kod utworzy metody hash­Code oraz equals, które nad­pisu­ją te domyślne, z klasy Object.

@ToString

Generu­je metodę toString() dla wybranej klasy. Meto­da ta domyśl­nie wyp­isze wartość wszys­t­kich pól w czytel­ny sposób. Przykład­owe użycie:

@ToString
public class Aplikacja {
    private String prywatnePole;
    private String publicznePole;
}

@RequiredArgsConstructor / @AllArgsConstructor / @NoArgsConstructor

Generu­je kon­struk­tor dla klasy, który przyj­mu­je jako argu­men­ty odpowied­nio: pola wyma­gane (pry­watne i finalne), wszys­tkie pola, nie przyj­mu­je argu­men­tów. Przykład­owe użycie:

@AllArgsConstructor
public class Aplikacja {
    private String prywatnePole;
    private String publicznePole;
}

Ta adno­tac­ja utworzy kon­struk­tor przyj­mu­ją­cy dwa argu­men­ty typu String, które zostaną przyp­isane do pól.

@Data

Adno­tac­ja ta łączy w sobie kil­ka innych: @Getter, @Setter, @HashCodeAndEquals, @RequiredArgsConstructor oraz @ToString. Zapis:

@Data
public class Aplikacja {
    private String prywatnePole;
    private String publicznePole;
}

Jest więc równoważny z poniższym:

@Getter
@Setter
@HashCodeAndEquals
@RequiredArgsConstructor
@ToString
public class Aplikacja {
    private String prywatnePole;
    private String publicznePole;
}

@Log i podobne

Ta adno­tac­ja pozwala dodać log­ger, jako pole o nazwie log. Do wyboru mamy najpop­u­larniejsze biblioteki:

@Log4j2 — Log4j w wer­sji 2
@Slf4j — Slf4J
@CommonsLog — Apache Com­mons Logging

Uwa­ga — adno­tac­je te nie doda­ją odpowied­nich bib­liotek! Musisz sama dodać zależnoś­ci do tych bibliotek.



		

Pozostałe adnotacje

Lom­bok ofer­u­je także kil­ka innych, użytecznych adno­tacji. @Builder czy @Synchronized pozwala­ją na uproszcze­nie kodu w specy­ficznych sytu­ac­jach, ale ich zas­tosowanie jest bardziej specy­ficzne. Po szczegółowy opis każdej z nich odsyłamy do doku­men­tacji pod adresem https://projectlombok.org/features/index.html

Podsumowanie

Lom­bok jest naprawdę świet­nym rozwiązaniem na ‘boil­er­plate code’ — wg nas zwięk­sza czytel­ność kodu i popraw­ia sen­sowność metryk takich jak np. pokrycie kodu. Zan­im jed­nak uży­jesz go w pro­jek­cie w pra­cy, upewnij się, że zespół nie ma nic prze­ci­wko! Jeśli jed­nak do tej pory nie uży­wal­iś­cie w zes­pole — może warto, żebyś zaproponowała?