Ответ
Паттерн Proxy (Заместитель) предоставляет суррогатный объект, контролирующий доступ к другому объекту. Основные типы: удаленный, виртуальный, защищающий, логирующий.
Пример защищающего прокси (Protection Proxy):
-
Общий интерфейс:
public interface DatabaseAccess { void query(String sql) throws AccessDeniedException; } -
Реальный объект:
public class RealDatabaseAccess implements DatabaseAccess { @Override public void query(String sql) { System.out.println("Executing query: " + sql); // Реальная логика выполнения запроса к БД } } -
Прокси-объект (добавляет контроль доступа):
public class DatabaseAccessProxy implements DatabaseAccess { private RealDatabaseAccess realService; private String userRole; public DatabaseAccessProxy(String userRole) { this.userRole = userRole; } @Override public void query(String sql) throws AccessDeniedException { // Дополнительная логика ПЕРЕД вызовом реального объекта if (!"ADMIN".equals(userRole)) { throw new AccessDeniedException("User '" + userRole + "' cannot execute queries."); } // Ленивая инициализация реального объекта if (realService == null) { realService = new RealDatabaseAccess(); } // Делегирование вызова реальному объекту realService.query(sql); // Здесь можно добавить логику ПОСЛЕ вызова (логирование, кэширование) System.out.println("Query executed by: " + userRole); } } -
Использование клиентом:
public class Client { public static void main(String[] args) { DatabaseAccess adminAccess = new DatabaseAccessProxy("ADMIN"); try { adminAccess.query("DELETE FROM users"); // Успешно } catch (AccessDeniedException e) { e.printStackTrace(); } DatabaseAccess userAccess = new DatabaseAccessProxy("USER"); try { userAccess.query("SELECT * FROM users"); // Выбросит AccessDeniedException } catch (AccessDeniedException e) { System.out.println("Expected error: " + e.getMessage()); } } }
Преимущества:
- Контроль доступа: Прокси проверяет права перед выполнением операции.
- Ленивая инициализация (Виртуальный прокси): Ресурсоемкий объект создается только при необходимости.
- Дополнительная функциональность: Легко добавить логирование, кэширование, управление соединениями без изменения реального объекта.