Skip to content

Паттерн Proxy (заместитель)

В этой теме мы разберем:

  • суть паттерна;
  • структуру его работы;
  • применимость и шаги реализации паттерна;
  • его отношения с другими паттернами.

Суть паттерна

Proxy (заместитель) — это структурный паттерн проектирования, который позволяет подставлять вместо реальных объектов специальные объекты-заменители. Эти объекты перехватывают вызовы к оригинальным объектам, позволяя сделать что-то до (или после) передачи им вызова.

Проблема

Для чего вообще необходимо контролировать доступ к объектам? Рассмотрим такой пример: у нас есть внешний ресурсоёмкий объект, который бывает нужен не все время, а только изредка.

Запросы к базе данных могут быть очень медленными

Мы могли бы создавать этот объект не в самом начале программы, а только тогда, когда он кому-то реально понадобится. Каждый клиент объекта получал бы некий код отложенной инициализации. Но, вероятно, это привело бы к множественному дублированию кода.

В идеале код хотелось бы поместить прямо в служебный класс, но это не всегда возможно (он может находиться, например, в закрытой сторонней библиотеке).

Решение

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

Заместитель «притворяется» базой данных, ускоряя работу за счёт ленивой инициализации и кеширования повторяющихся запросов

В чём же здесь польза? Мы можем поместить в класс заместителя какую-то промежуточную логику, которая будет выполняться до (или после) вызовов этих же методов в настоящем объекте. А благодаря одинаковому интерфейсу объект-заместитель можно передать в любой код, ожидающий сервисный объект.

Аналогия из жизни

Платёжной картой можно расплачиваться также, как и наличными.

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