3 FUNKCJE LOMBOKA, O KTÓRYCH NIE MIAŁEŚ POJĘCIA

three wise monkeys statuette on log at daytime

Zdradzę Ci sekret.

Lomboka używam w każdym projekcie z Javą z jaką mam styczność.

W każdym!

Zakładam, że Ty pewnie też.

Adnotacje @Data, @Value czy @RequiredArgsConstructor zaoszczędzają mi mnóstwo czasu.

(Java == Boilerplate code, itd ;).

Ale!

To nie wszystko funkcje, jakie skrywa w sobie Lombok.

Zobacz 3 ciekawe możliwości, o których być może nie miałeś do tej pory pojęcia!

1. Sneaky Throws

Genialna sprawa.

Adnotacja, dzięki której nie muszę deklarować tam i z powrotem CheckedExceptions, których i tak nie chcę w żaden sposób obsługiwać.

Albo gdy muszę zaimplementować interfejs, który nie deklaruje rzucania wyjątkami.

W takich sytuacjach sprawdza się znakomicie.

Przed korzystaniem z tej adnotacji kod może wyglądać tak.

class CustomerService {

    private ObjectMapper mapper;

    public Customer parseJson(String json) throws JsonParsingException {
        return mapper.readValue(json, Customer.class);
    }
}

Natomiast po dodaniu @SneakyThrows nie ma potrzeby pisać smutnego throws Json....Exception.

class CustomerService {

    private ObjectMapper mapper;

    @SneakyThrows
    public Customer parseJson(String json) {
        return mapper.readValue(json, Customer.class);
    }
}

Genialne! 🙂

2. Cleanup

Umówmy się.

Java powstała już jakiś czasu.

I nie każda konstrukcja języka jest przyjemna do czytania.

Jak na przykład zamykanie zasobów implementujących interfejs AutoClosable.

Przed Javą 7 wyglądało to tak:

public Customer parseFromFile(String file) {
    Customer customer = null;
    InputStream stream = new FileInputStream("foo.txt")
    try {
        customer = mapper.readValue(stream, Customer.class);
    } finally {
        stream.close();
    }
    return customer;
}

Od Javy 7 kwestia trochę się poprawiła.

Można wkładać zasób do bloku try-catch.

Zamknięty zostanie automatycznie.

public Customer parseFromFile(String file) {
    Customer customer = null;
    try (InputStream stream = new FileInputStream("foo.txt")) {
        customer = mapper.readValue(stream, Customer.class);
    }
    return customer;
}

Ale czy można lepiej?

Oczywiście!

Z pomocą przychodzi Cleanup z Lomboka 🙂

@SneakyThrows
public Customer parseFromFile(String file) {
    @Cleanup InputStream stream = new FileInputStream(file);
    return mapper.readValue(stream, Customer.class);
}

Zamiast 5 linii mamy 2! 🙂

3. Lazy Getter

Jak zaimplementować mechanizm leniwego inicjalizowania zmiennej?

Musimy podciągnąć rękawy, ubrudzić ręce i napisać taki smutny kodzik 👇

(Wzorzec podwójnego mechanizmu blokującego – double locking mechanism).

class Rates {
    private Map<String, BigDecimal> rates = new HashMap<>();
    private static final Object FETCH_LOCK = new Object();

    public Map<String, BigDecimal> getRates() {
        if(rates == null) {
            synchronized(FETCH_LOCK) {
                if(rates == null) {
                    rates = fetchRates();
                }
            }
        }
        return rates;
    }

    private Map<String, BigDecimal> fetchRates() {
        // make a long HTTP call
    }
}

17 linii i całkiem spore pole do popełnienia błędu..

A jak to wygląda z Lombokiem?

Dodajmy adnotację @Getter(lazy = true).

class Rates {
    @Getter(lazy = true)
    private final Map<String, BigDecimal> rates = fetchRates();

    private Map<String, BigDecimal> fetchRates() {
        // make a long HTTP call
    }
}

6 lini!

I ten sam efekt.

Skoro nie widać różnicy, to po co przepłacać? 🙂

…no chyba, że masz płacone za liczbę linii kodu…

Ale to już temat na inną rozmowę 😅

Szybkie podsumowanie.

  1. Lombok jest zajebisty.
  2. Adnotacje @Value, @Data czy @RequiredArgsConstructor zna większość programistów.
  3. Ale stosowanie innych konstrukcji jak: @SneakyThrows, @Cleanup czy @Getter(lazy = true) może wznieść Twój kodzik na jeszcze wyższy poziom.

A Ty? Znałeś te adnotacje? 🙂

8 Replies to “3 FUNKCJE LOMBOKA, O KTÓRYCH NIE MIAŁEŚ POJĘCIA

  1. Mnie ostatnio zadziwiła adnotacja @Builder z opcją toBuilder=true. Pozwala nie tylko na zrobienie obiektu z buildera, ale także buildera zainicjalizowanego wartościami obiektu. Wystarczy na obiekcie wywołać wygenerowana metodę toBuilder()

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.