Рассматривается структурный шаблон проектирования Proxy, приведено описание шаблона и пример реализации.
Содержание
- Область применения
- Реализация
- Итоги
У этого шаблона несколько имен: Proxy, Прокси, Заместитель. Мне больше нравится называть его proxy. Шаблон проектирования Прокси очень похож на рассмотренный ранее структурный шаблон проектирования Декоратор. Но если последний используют, чтобы расширить функции заменяемого класса, то у нашего другие задачи.
Область применения
Шаблон Proxy, как можно догадаться из названия, предполагает наличие промежуточного объекта, стоящего перед основным объектом. Прокси-объект должен содержать ссылку на основной объект и иметь аналогичный с ним интерфейс. Это позволяет возложить на него достаточно много дополнительных обязанностей, вот некоторые из них:
- управлять доступом к основному объекту в зависимости от прав доступа;
- замещать основной объект в некоторых случаях, например для экономии ресурсов сервера. Чаще всего при этом proxy берет на себя часть простых функций основного объекта, а оригинал создается только тогда, когда необходим ответ на «тяжелые» запросы;
- с помощью промежуточного proxy можно вводить дополнительный функционал, если сложно или нет возможности изменить основной объект.
И это, конечно, только некоторые возможности данного шаблона. Они определяются задачами проектирования и ограничены лишь вашей фантазией.
Реализация
Рассмотрим случай, когда с помощью Proxy шаблона хотят уменьшить нагрузку сервера. В примере реальный объект класса 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 объект самостоятельно выполняет простые операции сложения и вычитания, а для выполнения умножения и деления создает(если его нет) основной объект и с его помощью производит более трудоемкие вычисления.
Перейти к списку шаблонов проектирования.