Шаблон проектирования «Заместитель» (Proxy)
Шаблон проектирования «Заместитель» (Proxy) относится к категории структурных шаблонов, используемых в объектно-ориентированном программировании. Основная идея заключается в создании промежуточного объекта («заместителя»), который действует от имени основного объекта, контролируя доступ к нему и предоставляя возможность расширения функциональности без изменения самого объекта.
Суть паттерна
Задача заместителей — создать дополнительный уровень абстракции поверх существующего объекта. Это полезно в случаях, когда прямой доступ к основному объекту нежелателен или неэффективен, например, для оптимизации производительности, контроля безопасности или организации виртуализации ресурсов.
Типичные случаи использования:
- Отложенная загрузка тяжёлых ресурсов (ленивая инициализация)
- Управление правами доступа и проверка полномочий пользователей
- Добавление функционала вроде кеширования, авторизации, ведения журнала действий
- Организация удаленного взаимодействия (доступ к сетевым ресурсам)
Пример реализации на PHP
Допустим, у вас есть ресурсоемкий сервис, выполняющий вычисления. Чтобы оптимизировать производительность, мы можем применить принцип ленивой загрузки, используя шаблон «Заместитель».
Интерфейс сервиса:
interface MathService {
public function calculate($a, $b);
}
Реализация настоящего сервиса:
class HeavyMathService implements MathService {
private $initialized = false;
// Ресурсозатратный метод
public function initialize() {
echo "Инициализируем тяжелый сервис...\n";
sleep(2); // Моделируем задержку
$this->initialized = true;
}
public function calculate($a, $b) {
if (!$this->initialized) {
$this->initialize();
}
return $a + $b;
}
}
Заместитель для оптимизации:
class MathServiceProxy implements MathService {
private $heavyService;
public function calculate($a, $b) {
if ($this->heavyService === null) {
$this->heavyService = new HeavyMathService(); // Создаем настоящий объект только при первом обращении
}
return $this->heavyService->calculate($a, $b);
}
}
Использование заместителя:
$proxy = new MathServiceProxy();
echo $proxy->calculate(2, 3)."\n"; // Только теперь создаётся реальный объект
echo $proxy->calculate(5, 7)."\n"; // Второй раз создается мгновенно
Основные преимущества:
- Повышение эффективности благодаря отложенному созданию тяжелого ресурса.
- Упрощение добавления дополнительной логики (например, аутентификации, проверки прав доступа).
- Возможность управлять жизненным циклом объектов без модификации самих классов сервисов.
Этот шаблон полезен в сценариях, связанных с созданием медленных или тяжелых компонентов, которыми нужно пользоваться экономично и эффективно.