Lazy Load – Паттерны Объектно-Реляционной логики (PoEAA)
Загрузку данных в оперативную память следует организовать таким образом, чтобы при загрузке интересующего вас объекта из базы данных автоматически извлекались и другие связанные с ним объекты. Это значительно облегчает жизнь разработчика, которому в противном случае пришлось бы прописывать загрузку всех связанных объектов вручную. К сожалению, подобный процесс может принять устрашающие формы, если загрузка одного объекта повлечет за собой загрузку огромного количества связанных с ним объектов — крайне нежелательная ситуация, особенно когда вам были нужны только несколько конкретных записей. Типовое решение этой проблемы это шаблон проектирования Lazy Load (ленивая загрузка)
Паттерн Lazy Load (ленивая загрузка) подразумевает отказ от загрузки дополнительных данных, если в этом нет необходимости. Вместо этого ставится маркер о том, что данные не загружены и их надо загрузить в случае, если они понадобятся. Как известно, если вы ленивы, то вы выигрываете в том случае, если дело, которое вы не делали на самом деле и не надо было делать.
Существует четыре основных варианта ленивой загрузки:
Lazy Initialization
Ленивая Инициализация использует специальный макер (обычно null), чтобы пометить поле, как не загруженное. При каждом обращении к полю проверяется значение маркера и, если значение поля не загружено - оно загружается.
Пример рализации Lazy Initialization на C#
class Reader
{
Lazy<DetailsInfo> hugeObject = new Lazy<DetailsInfo>();
public void GetUsers()
{
hugeObject.Value.GetInfo();
Console.WriteLine("Читаем большой объект");
}
}
Virtual Proxy
Виртуальный Прокси - объект с таким же интерфейсом, как и настоящий объект. При первом обращении к методу объекта, виртуальный прокси загружает настоящий объект и перенаправляет выполнение.
Value Holder
Контейнер значения - объект с методом getValue. Клиент вызывает метод GetValue
, чтобы получить реальный объект. GetValue
вызывает загрузку.
Пример реализации Value Holder на C#
public class ValueHolder<T>
{
private T _value;
private readonly Func<object, T> _valueRetrieval;
// Constructor
public ValueHolder(Func<object, T> valueRetrieval)
{
_valueRetrieval = valueRetrieval;
}
public T GetValue(object parameter)
{
if (_value == null)
_value = _valueRetrieval(parameter);
return _value;
}
}
Ghost
Призрак - объект без каких-либо данных. При первом обращении к его методу, призрак загружает все данные сразу.