Рассматривается структурный шаблон проектирования Прокси, приведено описание шаблона и пример реализации.
У этого шаблона несколько имен: 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);
}
}
Перейти к списку шаблонов проектирования.