Рассматривается структурный шаблон проектирования Proxy, приведено описание шаблона и пример реализации на PHP.
Содержание
- Применение
- Структура шаблона
- Реализация
- Итоги
У этого шаблона несколько имен: Proxy, Прокси, Заместитель.
Шаблон проектирования Proxy очень похож на рассмотренный ранее структурный шаблон проектирования Декоратор. Но если последний используют, чтобы расширить функции заменяемого класса, то у нашего другие задачи.
Применение
Шаблон проектирования Proxy, как можно догадаться из названия, предполагает наличие промежуточного объекта, стоящего между клиентом и объектом запроса. При этом прокси-объект должен содержать ссылку на объект запроса и иметь аналогичный с ним интерфейс. Такое построение позволяет возложить на него достаточно много дополнительных обязанностей, вот некоторые из них:
- управлять доступом к основному объекту в зависимости от прав доступа;
- замещать основной объект в некоторых случаях, например для экономии ресурсов сервера. Чаще всего при этом Proxy берет на себя часть простых функций основного объекта, а оригинал создается только тогда, когда необходим ответ на «тяжелые» запросы;
- с помощью промежуточного Proxy можно вводить дополнительный функционал, если сложно или нет возможности изменить основной объект.
И это, конечно, только некоторые возможности данного шаблона. Они определяются задачами проектирования и ограничены лишь вашей фантазией.
Структура шаблона
В приводимом примере с помощью шаблона Proxy будем уменьшать нагрузку на сервер. В примере будут использоваться такие структуры.
- IMath — интерфейс, определяющий функционал сервера.
- Math — класс основного объекта, производящего вычисления, реализует интерфейс IMath.
- MathProxy — класс прокси объекта, также реализует интерфейс IMath.
Наш прокси берёт на себя вычисление простых арифметических операций. При запросе вычисления более сложный действий он обращается к объекту класса Math и затем транслирует клиенту результат вычислений.
Реализация
Итак, вначале определяем интерфейс нашего вычислителя.
interface IMath
{
public function add($operand1, $operand2);
public function subj($operand1, $operand2);
public function mul($operand1, $operand2);
public function div($operand1, $operand2);
}
Теперь определим основной вычислитель.
class Math implements IMath
{
public function add($oper1, $oper2)
{
return $oper1 + $oper2;
}
public function subj($oper1, $oper2)
{
return $oper1 - $oper2;
}
public function mul($oper1, $oper2)
{
return $oper1 * $oper2;
}
public function div($oper1, $oper2)
{
return $oper1 / $oper2;
}
}
Наш прокси-объект, будет выполнять операции сложения и вычитания самостоятельно, а умножение и деление переадресовать подменяемому объекту.
class MathProxy implements IMath
{
protected $math = null;
public function add($oper1, $oper2)
{
return $oper1 + $oper2;
}
public function subj($oper1, $oper2)
{
return $oper1 - $oper2;
}
public function mul($oper1, $oper2)
{
if ($this->math === null) {
$this->math = new Math();
}
return $this->math->mul($oper1, $oper2);
}
public function div($oper1, $oper2)
{
if ($this->math === null) {
$this->math = new Math();
}
return $this->math->div($oper1, $oper2);
}
}
Надеюсь, из код достаточно простой — при запросе клиента, прокси выполняет сложение и вычитание самостоятельно. Для выполнения остальных операций он создает основной вычислитель, если его нет, и вызывает у него требуемый метод, после чего возвращает результат.
Итоги
Итак, вы познакомились с шаблоном проектирования Proxy, выполняющим роль посредника между клиентом и основным объектом запроса. Такое взаимодействие имеет массу возможностей, вот лишь некоторые из них.
- Снижение нагрузки на основной объект за счет выполнения части его функций.
- Управление доступом к основному объекту.
- Ленивая инициализация основного объекта, когда ресурсоёмкий объект создается лишь в случае его необходимости.
Как вы понимаете, этот список можно еще долго дополнять.
К недостаткам следует отнести некоторое усложнение кода и в некоторых случаях дополнительная задержка ответа, когда исполнение запроса транслируется основному объекту.
Перейти к списку шаблонов проектирования.