Lipiec 24, 2019

Czym jest lazy loading?

Lazy loading

Lazy loading lub inaczej leniwa inicjalizacja jest wzorcem projektowym, który zapewnia, że inicjalizacja obiektu nastąpi jak najpóźniej jest to możliwe.

W skrócie, obiekt jest inicjalizowany w momencie, gdy jest potrzebny, użytkownik chce go użyć.

Takim momentem może być np. wczytanie dużej kolekcji danych lub wykonanie skomplikowanego algorytmu.

Korzystanie z tego wzorca projektowego zapewnia zaoszczędzenie pamięci lub możliwość przesunięcia wykorzystania mocy obliczeniowej do momentu, gdy faktycznie obiekt jest nam potrzebny do dalszych operacji.

W przypadku wywoływania skomplikowanych algorytmów może się okazać, że jego wywołanie poszło na marne i wynik jego działania nie został użyty, więc czemu by nie korzystać z dobrodziejstw z tego wzorca?

Jak go zaimplementować?

Prostą implementację tego wzorca można napisać na szybko i przykładem może być popularny wzorzec Singleton z tzw. opóźnioną inicjalizacją instancji.

package pl.blog;

public class IssueService {
    private static IssueService instance = null;

    public static IssueService getInstance() {
        if (instance == null) {
            instance = new IssueService();
        }

        return instance;
    }

    private IssueService() {}
}

W tym przypadku inicjalizacja obiektu IssueService zostaje przesunięta, aż do momentu, gdy ktoś faktycznie zacznie korzystać z owej klasy. Zysk niby mały, dlatego prawdopodobnie rzadziej spotykany.

Głównem przeznaczenie wykorzystania lazy loadingu jest wczytywanie dużych kolekcji, w momencie gdy mamy relacyjną bazę danych i wyciągamy encję, która w sobie zawiera listę innych obiektów – podkreślmy, że ta lista jest długa.

Kwestią lazy loadingu w naszych projektach zazwyczaj zajmuje się Hibernate i jest to domyślna opcja dla mapowania obiektów.

Jako ciekawostkę dodam, że można to łatwo zmienić wybierając opcję EAGER np.:

@ManyToMany(mappedBy = "workers", fetch = FetchType.EAGER)
private List<Company> companiesWorker;

@ManyToMany(mappedBy = "experts", fetch = FetchType.LAZY)
private List<Company> companiesExpert;

Wybierając taką opcję, Hibernate dopiero w momencie skorzystania z listy companiesWorker zaciągnie nam dane z bazy danych.