Ответ
Ленивая загрузка (Lazy Loading) — это паттерн отложенной инициализации, при котором ресурсоёмкий объект или данные создаются/загружаются не в момент создания родительского объекта, а только при первом обращении к ним.
Цель: оптимизация производительности и потребления памяти за счёт загрузки только необходимых в данный момент ресурсов.
Ключевой принцип: "Не делай работу, пока в ней нет необходимости".
Пример реализации на Java с Supplier:
public class Lazy<T> {
private Supplier<T> supplier;
private T value;
private volatile boolean initialized = false; // для потокобезопасности
public Lazy(Supplier<T> supplier) {
this.supplier = supplier;
}
public T get() {
if (!initialized) {
synchronized (this) {
if (!initialized) { // Double-checked locking
value = supplier.get(); // Дорогая операция выполняется здесь
initialized = true;
}
}
}
return value;
}
}
// Использование
Lazy<ExpensiveObject> lazyResource = new Lazy<>(() -> {
System.out.println("Creating expensive object...");
return new ExpensiveObject(); // Создание происходит только при первом get()
});
// Объект ExpensiveObject ещё не создан
ExpensiveObject obj = lazyResource.get(); // Создание происходит сейчас
ExpensiveObject obj2 = lazyResource.get(); // Возвращается уже созданный объект
Типичные примеры применения:
- ORM (Hibernate/JPA): Загрузка связанных коллекций (
@OneToMany(fetch = FetchType.LAZY)). Коллекция загружается только при явном обращении кgetItems(). - Загрузка ресурсов: Изображения на веб-странице загружаются по мере прокрутки (lazy load images).
- Создание тяжёлых объектов: Конфигурации, подключения к БД, которые могут не понадобиться.
Альтернатива: Eager Loading (жадная загрузка), когда все связанные данные загружаются сразу.