Паттерн proxy (он же паттерн заместитель) — это структурный паттерн из книги банды четырех.
Прокси — это объект посередине, это подмена реального объекта, прокси класс замещает реальный объект. Вместо того, чтобы клиент напрямую вызывал какой-либо объектный метод, входящий вызов сначала получает объект прокси, и взаимодействие с методами реального объекта уже происходит через него.
Прокси похож на паттерн декоратор, но декоратор это всегда привнесение нового функционала, а паттерн прокси имеет цель именно подмену реального объекта на объект прокси.
Из часто используемых случаев паттерна Proxy можем выделить:
- Virtual proxy используется для задержки инициализации создания реального объекта или для упрощения объекта. Когда для загрузки объекта требуется некоторое время (из БД или файловой системы например), вы можете использовать этот прокси для создания объекта только тогда, когда это абсолютно необходимо. Хороший пример это прокси класс для entity в библиотеке Doctrine когда обращение к БД для получения entity произойдет только в случае, если действительно понадобится объект (но это может порождать проблему 1+N запросов к БД).
- Remote proxy полезен, когда вы хотите обращаться с удаленным ресурсом, как если бы он был локальным. Например в приложении идет запрос к удаленным системам по SOAP WSDL или API.
- Protection proxy предотвращает доступ к методам. UnauthenticatedProxy может не разрешать определенные методы своему базовому классу при определенных условиях, например когда такой метод вызывает сервис с недостаточными правами для этого.
- Smart proxy (логирующий proxy) добавляет дополнительную функциональность обернутому объекту. Запуск события или запись в файл журнала при вызове метода объекта не нарушает исходный код объекта. Это похоже на декоратор, но вы не добавляете к объекту реальную дополнительную видимую функциональность.
Таким образом основные случаи употребления паттерна:
- для замены функций защиты,
- производительности,
- для упрощения реального объекта.
Реализация
Для паттерна proxy имеется 3 составляющих:
- интерфейс, иногда допускается использование абстрактного класса.
- реальный класс.
- прокси класс.

Особенности реализации паттерна:
- реальный класс и прокси класс реализуют один и тот же интерфейс. Благодаря этому класс прокси можно использовать в местах кода, где ожидается реальный класс (если конечно вы делаете согласно SOLID и внедряете зависимости через интерфейсы).
- Прокси класс содержит объект реального класса через композицию, либо создает этот объект в момент когда система запрашивает общий метод из интерфейса.
- Система работает с реальным классом только через общий интерфейс, поэтому прокси класс корректно его подменяет незаметно для системы.