Ответ
Паттерн Прокси (Proxy) предоставляет объект-заместитель, который контролирует доступ к другому объекту, добавляя дополнительную логику (ленивую инициализацию, контроль доступа, логирование).
Пример: Ленивая загрузка (Lazy Loading) тяжелого объекта.
// 1. Общий интерфейс для реального объекта и прокси
interface ExpensiveService {
void process();
}
// 2. Реальный объект с "тяжелой" инициализацией
class ExpensiveServiceImpl implements ExpensiveService {
public ExpensiveServiceImpl() {
// Долгая операция: загрузка из БД, чтение файла и т.д.
System.out.println("Creating real ExpensiveService...");
}
@Override
public void process() {
System.out.println("Processing by real service.");
}
}
// 3. Прокси-заместитель, откладывающий создание реального объекта
class ExpensiveServiceProxy implements ExpensiveService {
private ExpensiveService realService; // Ссылка на реальный объект
@Override
public void process() {
// Ленивая инициализация: создаем объект только при первом вызове
if (realService == null) {
realService = new ExpensiveServiceImpl();
}
// Делегируем вызов реальному объекту
realService.process();
}
}
// 4. Использование клиентом
public class Client {
public static void main(String[] args) {
// Реальный объект еще не создан
ExpensiveService proxy = new ExpensiveServiceProxy();
System.out.println("Proxy created.");
// Реальный объект создается только здесь, при первом вызове
proxy.process();
}
}
Другие типы прокси и их применение:
- Виртуальный прокси (как в примере): Для ленивой загрузки ресурсов.
- Защищающий прокси (Protection Proxy): Для контроля прав доступа к объекту.
- Удаленный прокси (Remote Proxy): Для представления объекта, находящегося в другом адресном пространстве (например, RPC, REST-клиент).
- Прокси для логирования/кэширования: Добавляет сквозную функциональность.
Почему это полезно: Улучшает производительность и безопасность, разделяя ответственности.