Заместитель (Proxy)
Другое название
Суррогат (Surrogate)
Назначение
Заместитель ведет себя точно так же как и основной объект, выполняя при необходимости его инстанцирование.
Описание
В некоторых ситуациях расходы на создание и инициализацию объекта можно отложить до тех пор пока он действительно понадобится. Особенно заметен выигрыш - для тяжеловесных объектов, которые разумно создавать "по требованию".
В этом случае вместо самого объекта инстанцируется его Заместитель, а когда с объектом становится необходимо работать, инстанцируется сам объект.Например, в текстовом документе сбольшим количеством тяжеловесных изображений нет необходимости при открытии документа открывать и отображать все изображения. Необходимость в отображении изображения возникает лишь при переходе к области документа, в которой это изображение расположено.
Заместитель следует интерфейсу основного объекта, хранит ссылку на него и инстанцирует его по требованию.
Использование
Заместитель используется в следующих ситуациях.
- Удаленный заместитель предоставляет локального представителя вместо объекта, находящегося в другом адресном пространстве.
- Виртуальный заместитель создает "тяжелые" объекты по требованию.
- Защищающий заместитель ограничивает права доступа к объекту.
- Умная ссылка позволяет выполнить дополнительные действия при доступе к объекту - например, загрузить объект в память при первом доступе к нему или заблокировать объект при обращении к нему.
Реализация
Диаграмма классов
Участники
- Proxy - заместитель
- Хранит ссылку, которая позволяет Заместителю обратиться к реальному субъекту
- Предоставляет интерфейс, идентичный Subject
- Контролирует доступ к реальному субъекту и отвечает за его создание и удаление
- Subject - субъект
Определяет общий для RealSubject и Proxy интерфейс, так что объект Proxy может использоваться везде где используется RealSubject
- RealSubject
Определяет реальный объект, представленный Заместителем
Код
class MainApp
{
static void Main()
{
Proxy proxy = new Proxy();
proxy.Request();
Console.ReadKey();
}
}
abstract class Subject
{
public abstract void Request();
}
class RealSubject : Subject
{
public override void Request()
{
Console.WriteLine("Called RealSubject.Request()");
}
}
class Proxy : Subject
{
private RealSubject realSubject;
public override void Request()
{
if (realSubject == null)
{
realSubject = new RealSubject();
}
realSubject.Request();
}
}
Достоинства и недостатки
- При доступе к объекту вводится дополнительный уровень косвенности, позволяющий решать ряд проблем:
- для удаленного заместителя - сокрытие того факта что он находится в другом адресном пространстве
- для виртуального заместителя - можно выполнять создание объекта по требованию
Варианты
Приведены в пункте Использование:
- Удаленный заместитель,
- Виртуальный заместитель,
- Защищающий заместитель,
- Умная ссылка