Шаблон прокси

В паттерне Заместитель один класс представляет функциональность другого класса. Этот тип паттерна проектирования является структурным паттерном.

Паттерн заместитель управляет доступом к исходному объекту, вводя прокси-объект. Прокси-объект выступает посредником между клиентом и целевым объектом, отвечает за переадресацию запросов клиента целевому объекту и может выполнять дополнительную обработку до и после переадресации запроса.

В паттерне заместитель мы создаём объект, который содержит существующий объект, чтобы предоставить функциональный интерфейс внешнему миру.

Введение

назначение

Предоставить заместителя для другого объекта, чтобы контролировать доступ к этому объекту.

Основные решаемые проблемы

  • Паттерн заместитель решает проблемы, которые могут возникнуть при прямом доступе к некоторым объектам, такие как высокая стоимость создания объекта, необходимость контроля безопасности или удалённый доступ.

Сценарий использования

  • Когда необходимо выполнить некоторый контроль или дополнительную обработку при доступе к объекту.

Подход к реализации

  • Добавьте промежуточный слой: Создайте прокси-класс как промежуточный слой для реального объекта.
  • Композиция прокси и реального объекта: Прокси-класс хранит ссылку на реальный объект и контролирует доступ при обращении к нему.

Ключевой код

  • Прокси-класс: Реализует тот же интерфейс, что и реальный объект, и добавляет дополнительную логику контроля.
  • Реальный объект: объект, который фактически выполняет задачу.

Пример приложения

  • Ярлык: Ярлыки в системе Windows выступают в роли прокси для файлов или программ.
  • Ролевая игра: Сунь Укун выступает в роли прокси для Гао Цуйлань, и Чжу Бацзе не может их различить.
  • Пункт продажи: При покупке железнодорожных билетов билетное агентство выступает в роли прокси для железнодорожного вокзала.
  • чек: Как прокси для средств на банковском счете, контролирует доступ к средствам.
  • Spring AOP: Использование паттерна прокси для реализации аспектно-ориентированного программирования.

Преимущества

  • Разделение ответственности: Паттерн прокси отделяет контроль доступа от бизнес-логики.
  • Расширяемость: Гибко позволяет добавлять дополнительную функциональность или контроль.
  • Интеллектуальность: Он может интеллектуально обрабатывать запросы доступа, например ленивую загрузку, кэширование и т. д.

Недостатки

  • Накладные расходы на производительность: Добавление прокси-слоя может повлиять на скорость обработки запросов.
  • Сложность реализации: Некоторые типы паттерна прокси могут быть сложнее в реализации.

Рекомендации по использованию

  • Выбирайте подходящий тип прокси в соответствии с конкретными потребностями, например удалённый прокси, виртуальный прокси, защитный прокси и т. д.
  • Убедитесь, что интерфейс класса прокси согласован с реальным объектом, чтобы клиенты могли прозрачно использовать прокси.

Примечания

  • Отличие от паттерна Адаптер: Паттерн Адаптер изменяет интерфейс, тогда как паттерн Прокси не изменяет интерфейс.
  • Отличие от паттерна Декоратор: Паттерн Декоратор используется для расширения функциональности, тогда как паттерн Прокси используется для контроля доступа.

Структура

В основном он включает следующие ключевые роли:

  • Абстрактный субъект:

    • Определяет общий интерфейс для реального субъекта и прокси-субъекта, чтобы прокси-субъект можно было использовать везде, где используется реальный субъект.
  • Реальный субъект:

    • Реализует интерфейс абстрактного субъекта и является реальным объектом, представляемым прокси-объектом. Клиент напрямую обращается к реальному субъекту, но в некоторых случаях к нему можно обратиться косвенно через прокси-субъект.
  • Прокси:

    • Реализует интерфейс абстрактного субъекта и содержит ссылку на реальный субъект. Прокси-субъект обычно предоставляет некоторую дополнительную функциональность поверх реального субъекта, такую как ленивая загрузка, контроль разрешений, логирование и т. д.
  • Клиент:

    • Использует абстрактный интерфейс субъекта для работы с реальным субъектом или прокси-субъектом, без необходимости знать, какой именно это конкретный класс реализации.

Реализация

Мы создадим интерфейсImageи реализуем класс сущности интерфейсаImage.ProxyImageявляется прокси-классом, уменьшаяRealImageобъём памяти при загрузке объекта.

ProxyPatternDemoИспользование классаProxyImageдля получения загружаемогоImageобъекта и отображения его по мере необходимости.

代理模式的 UML 图

Шаг 1

Создайте интерфейс.

Image.java

public interface Image { void display(); }

Шаг 2

Создайте класс сущности, реализующий интерфейс.

RealImage.java

public class RealImage implements Image { private String fileName; public RealImage(String fileName){ this.fileName = fileName; loadFromDisk(fileName); } @Override public void display() { System.out.println("Отображение " + fileName); } private void loadFromDisk(String fileName){ System.out.println("Загрузка " + fileName); } }

ProxyImage.java

public class ProxyImage implements Image{ private RealImage⟦⟧realImage realImage; private String fileName; public ProxyImage(String fileName){ this.fileName = fileName; } @Override public void display() { if(realImage == null){ realImage = new RealImage(fileName); } realImage.display(); } }

Шаг 3

При запросе используйтеProxyImageчтобы получитьRealImageобъект класса.

ProxyPatternDemo.java

public class ProxyPatternDemo { public static void main(String[] args) { Image image = new ProxyImage("test_10mb.jpg"); //Изображение будет загружено с диска image.display(); System.out.println(""); //Изображения не нужно загружать с диска image.display(); } }

Шаг 4

Запустите программу и выведите результат:

Loading test_10mb.jpg
Displaying test_10mb.jpg

Displaying test_10mb.jpg
Другие расширения