Skip to content

Latest commit

 

History

History
103 lines (64 loc) · 10.9 KB

Proxy.md

File metadata and controls

103 lines (64 loc) · 10.9 KB

Заместитель

UML

Предоставляет суррогатный объект, управляющий доступом к другому объекту.

Виды:

  • (Ex) Удалённый заместитель (remote proxies): обеспечивает связь с «Субъектом», который находится в другом адресном пространстве или на удалённой машине. Также может отвечать за кодирование запроса и его аргументов и отправку закодированного запроса реальному «Субъекту»;

  • (Ex) Виртуальный заместитель (virtual proxies): Lazy loading обеспечивает создание реального «Субъекта» только тогда, когда он действительно понадобится. Также может кэшировать часть информации о реальном «Субъекте», чтобы отложить его создание;

  • (Ex) Защищающий заместитель (protection proxies): может проверять, имеет ли вызывающий объект необходимые для выполнения запроса права;

  • (Ex) Кэширующий прокси: обеспечивает временное хранение результатов расчёта до отдачи их множественным клиентам, которые могут разделить эти результаты;

  • Копировать-при-записи: обеспечивает копирование «субъекта» при выполнении клиентом определённых действий (частный случай «виртуального прокси»);

  • Протоколирующий прокси: сохраняет в лог все вызовы «Субъекта» с их параметрами;

  • Экранирующий прокси: защищает «Субъект» от опасных клиентов (или наоборот);

  • Синхронизирующий прокси: производит синхронизированный контроль доступа к «Субъекту» в асинхронной многопоточной среде;

  • «Умная» ссылка (smart reference proxy): производит дополнительные действия, когда на «Субъект» создается ссылка, например, рассчитывает количество активных ссылок на «Субъект».

Применимость

  • Ленивая инициализация (виртуальный прокси). Когда у вас есть тяжёлый объект, грузящий данные из файловой системы или базы данных.

    • Вместо того чтобы грузить данные сразу после старта программы, можно сэкономить ресурсы и создать объект тогда, когда он действительно понадобится.
  • Защита доступа (защищающий прокси). Когда в программе есть разные типы пользователей и вам хочется защищать объект от неавторизованного доступа. Например, если ваши объекты - это важная часть операционной системы, а пользователи - сторонние программы (хорошие или вредоносные).

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

    • В этом случае заместитель транслирует запросы клиента в вызовы по сети, в протоколе, понятном удалённому сервису.
  • Логирование запросов (логирующий прокси). Когда требуется хранить историю обращений к сервисному объекту.

    • Заместитель может сохранять историю обращения клиента к сервисному объекту.
  • Кеширование объектов («умная» ссылка) (Похоже на Объектный пул) Когда нужно кешировать результаты запросов клиентов и управлять их жизненным циклом.

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

      Кроме того, Заместитель может отслеживать, не менял ли клиент сервисный объект. Это позволит использовать объекты повторно и сильно экономить ресурсы, особенно если речь идёт о больших прожорливых сервисах.

Шаги реализации

  1. Определите интерфейс, который бы сделал заместитель и оригинальный объект взаимозаменяемыми.

  2. Создайте класс заместителя. Он должен содержать ссылку на сервисный объект. Чаще всего, сервисный объект создаётся самим заместителем. В редких случаях, заместитель получает готовый сервисный объект от клиента через конструктор.

  3. Реализуйте методы заместителя в зависимости от его предназначения. В большинстве случаев, проделав какую-то полезную работу, методы заместителя должны передать запрос сервисному объекту.

  4. Подумайте о введении фабрики, которая решала бы какой из объектов создавать - заместитель или реальный сервисный объект. Но с другой стороны, эта логика может быть помещена в создающий метод самого заместителя.

  5. Подумайте, не реализовать ли вам ленивую инициализацию сервисного объекта при первом обращении клиента к методам заместителя.

Преимущества и недостатки

+ -
Позволяет контролировать сервисный объект незаметно для клиента. Увеличивает время отклика от сервиса.
Может работать, даже если сервисный объект ещё не создан. Усложняет программу за счёт дополнительных классов.
Может контролировать жизненный цикл служебного объекта.

Отношения с другими паттернами

  • Адаптер предоставляет классу альтернативный интерфейс. Декоратор предоставляет расширенный интерфейс. Заместитель предоставляет тот же интерфейс.

  • Фасад похож на Заместитель тем, что замещает сложную подсистему и может сам её инициализировать. Но в отличие от Фасада, Заместитель имеет тот же интерфейс, что его служебный объект, благодаря чему их можно взаимозаменять.

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