Ответ
Паттерн Proxy (Заместитель) — это структурный паттерн проектирования, который предоставляет объект-заменитель или placeholder для другого объекта. Прокси контролирует доступ к оригинальному объекту, позволяя выполнить дополнительную логику до или после основного вызова.
Классическая структура:
Subject(Интерфейс): Общий интерфейс для RealSubject и Proxy.RealSubject(Реальный объект): Основной объект, содержащий бизнес-логику.Proxy(Заместитель): Объект, хранящий ссылку на RealSubject, управляет доступом к нему.
Пример: Virtual Proxy для ленивой загрузки изображения
// Subject
interface Image {
void display();
}
// RealSubject
class RealImage implements Image {
private String fileName;
public RealImage(String fileName) {
this.fileName = fileName;
loadFromDisk(); // Ресурсоемкая операция
}
private void loadFromDisk() { System.out.println("Loading: " + fileName); }
public void display() { System.out.println("Displaying: " + fileName); }
}
// Proxy
class ProxyImage implements Image {
private RealImage realImage;
private String fileName;
public ProxyImage(String fileName) { this.fileName = fileName; }
public void display() {
if (realImage == null) {
realImage = new RealImage(fileName); // Создание отложено до первого вызова
}
realImage.display();
}
}
// Клиентский код
Image image = new ProxyImage("photo.jpg");
image.display(); // Вывод: "Loading: photo.jpg" -> "Displaying: photo.jpg"
image.display(); // Вывод: "Displaying: photo.jpg" (объект уже загружен)
Основные типы прокси:
- Виртуальный прокси (Virtual Proxy): Откладывает создание ресурсоемкого объекта до момента его реального использования (ленивая загрузка).
- Защищающий прокси (Protection Proxy): Контролирует доступ к объекту на основе прав вызывающего кода.
- Удаленный прокси (Remote Proxy): Представляет локальную заглушку для объекта, находящегося в другом адресном пространстве (например, RMI, gRPC).
- Кэширующий прокси (Caching Proxy): Сохраняет результаты запросов и возвращает кэшированные данные для повторных вызовов.
- Логирующий прокси (Logging Proxy): Регистрирует вызовы методов и их параметры.
В Java прокси часто создаются динамически с помощью java.lang.reflect.Proxy или библиотек (например, Spring AOP).