Ответ
Паттерн Proxy (Заместитель) — это структурный паттерн, предоставляющий объект-заменитель или placeholder для другого объекта. Прокси контролирует доступ к оригинальному объекту, позволяя выполнять дополнительную логику до или после основного вызова.
Основные сценарии использования:
- Ленивая инициализация (Virtual Proxy): Отложить создание ресурсоёмкого объекта до момента реальной необходимости.
- Контроль доступа (Protection Proxy): Проверить права доступа перед вызовом методов реального объекта.
- Кеширование (Cache Proxy): Сохранять результаты дорогостоящих операций и возвращать кешированные данные.
- Логирование и мониторинг: Записывать вызовы методов, время выполнения.
- Удалённый доступ (Remote Proxy): Представлять объект, находящийся в другом адресном пространстве (например, при использовании удалённых сервисов).
Типы Proxy:
- Virtual Proxy – откладывает создание ресурсоемкого объекта.
- Protection Proxy – контролирует доступ к объекту.
- Remote Proxy – представляет объект в другом адресном пространстве.
- Smart Proxy – добавляет дополнительную логику (кеширование, логирование).
Пример (Virtual Proxy на C#):
// Интерфейс, общий для реального объекта и прокси
public interface IImage
{
void Display();
}
// Реальный, «тяжёлый» объект
public class RealImage : IImage
{
private string _fileName;
public RealImage(string fileName)
{
_fileName = fileName;
LoadFromDisk(); // Дорогая операция
}
private void LoadFromDisk() => Console.WriteLine($"Loading image '{_fileName}' from disk...");
public void Display() => Console.WriteLine($"Displaying image '{_fileName}'");
}
// Прокси-объект
public class ProxyImage : IImage
{
private RealImage _realImage;
private string _fileName;
public ProxyImage(string fileName) => _fileName = fileName;
public void Display()
{
// Создаём реальный объект только при первом вызове
if (_realImage == null)
{
_realImage = new RealImage(_fileName);
}
_realImage.Display();
}
}
// Использование
var image = new ProxyImage("high_res_photo.jpg");
// RealImage ещё не создан
image.Display(); // Вывод: "Loading image 'high_res_photo.jpg' from disk..." затем "Displaying image 'high_res_photo.jpg'"
image.Display(); // Вывод: "Displaying image 'high_res_photo.jpg'" (объект уже загружен)
Практическое применение: В .NET паттерн Proxy лежит в основе многих технологий, таких как:
- Entity Framework Core (ленивая загрузка навигационных свойств).
- МОК-объекты в юнит-тестах (например, в Moq или NSubstitute).
- WCF/Remoting клиенты для удалённых сервисов.