Proxy (шаблон проектирования)

Материал из Seo Wiki - Поисковая Оптимизация и Программирование
Перейти к навигацииПерейти к поиску

Шаблон Proxy (Заместитель) — Шаблон проектирования. Предоставляет объект, который контролирует доступ к другому объекту через перехват всех вызовов.

Цель

Проблема

Необходимо управлять доступом к объекту, так чтобы создавать громоздкие объекты «по требованию».

Решение

Создать суррогат громоздкого объекта. «Заместитель» хранит ссылку, которая позволяет заместителю обратиться к реальному субъекту (объект класса «Заместитель» может обращаться к объекту класса «Субъект», если интерфейсы «Реального Субъекта» и «Субъекта» одинаковы). Поскольку интерфейс «Реального Субъекта» идентичен интерфейсу «Субъекта», так, что «Заместителя» можно подставить вместо «Реального Субъекта», контролирует доступ к «Реальному Субъекту», может отвечать за создание или удаление «Реального Субъекта». «Субъект» определяет общий для «Реального Субъекта» и «Заместителя» интерфейс, так, что «Заместитель» может быть использован везде, где ожидается «Реальный Субъект». При необходимости запросы могут быть переадресованы «Заместителем» «Реальному Субъекту».

Диаграмма классов шаблона проектирования Proxy

Шаблон proxy бывает нескольких видов, а именно:

  • Удаленный: обеспечивает связь с «Субъектом» который находится в другом адресном пространстве или на удалённой машине. Так же может отвечать за кодирование запроса и его аргументов и отправку закодированного запроса реальному «Субъекту»,
  • Виртуальный: Обеспечивает создание реального «Субъекта» только тогда, когда он действительно понадобится. Так же может кэшировать часть информации о реальном «Субъекте», чтобы отложить его создание,
  • Копировать-при-записи:: Обеспечивает копирование «субъекта» при выполнении клиентом определённых действий. Частный случай «виртуального прокси»
  • Защищающий: может проверять, имеет ли вызывающий объект необходимые для выполнения запроса права.
  • Кэширующий прокси: Обеспечивает временное хранение результатов расчёта до отдачи множественным клиентам, которые могут разделить эти результаты.
  • Экранирующий прокси: Защищает «Субъект» от опасных клиентов (или наоборот).
  • Синхронизирующий прокси: Производит синхронизированный контроль доступа к «Субъекту» в асинхронной многопоточной среде.
  • Smart reference proxy: Производит дополнительные действия когда на «Субъект» создается ссылка, например рассчитывает количество активных ссылок на «Субъект».

Плюсы

  •  удаленный заместитель;
  •  виртуальный заместитель может выполнять оптимизацию;
  •  защищающий заместитель;
  • "умная" ссылка;

Минусы

  • резкое увеличение времени отклика.

Применимость

Шаблон Proxy может применяться в таких случаях работы с сетевым соединением, огромным объектом в памяти (или на диске) или любым другим ресурсом который сложно или тяжело копировать. Хорошо известный пример применения — объект подсчитывающий число ссылок.

Примеры

Java

<source lang="java"> public class Main {

public static void main(String[] args) { // Create math proxy IMath p = new MathProxy();

// Do the math System.out.println("4 + 2 = " + p.add(4, 2)); System.out.println("4 - 2 = " + p.sub(4, 2)); System.out.println("4 * 2 = " + p.mul(4, 2)); System.out.println("4 / 2 = " + p.div(4, 2)); } }

/**

* "Subject"
*/

public interface IMath {

public double add(double x, double y);

public double sub(double x, double y);

public double mul(double x, double y);

public double div(double x, double y); }

/**

* "Real Subject"
*/

public class Math implements IMath {

public double add(double x, double y) { return x + y; }

public double sub(double x, double y) { return x - y; }

public double mul(double x, double y) { return x * y; }

public double div(double x, double y) { return x / y; }

}

/**

* "Proxy Object"
*/

public class MathProxy implements IMath {

private Math math;

public MathProxy() { math = new Math(); }

public double add(double x, double y) { return math.add(x, y); }

public double sub(double x, double y) { return math.sub(x, y); }

public double mul(double x, double y) { return math.mul(x, y); }

public double div(double x, double y) { return math.div(x, y); } } </source>

C++

<source lang="cpp"> /**

* "Subject"
*/

class IMath { public:

   virtual double add(double x, double y) = 0;
   virtual double sub(double x, double y) = 0;
   virtual double mul(double x, double y) = 0;
   virtual double div(double x, double y) = 0;

};

/**

* "Real Subject"
*/

class Math : public IMath { public:

   double add(double x, double y) {
       return x + y;
   }
   
   double sub(double x, double y) {
       return x - y;
   }
   
   double mul(double x, double y) {
       return x * y;
   }
   
   double div(double x, double y) {
       return x / y;
   }

};

/**

* "Proxy Object"
*/

class MathProxy : public IMath { public:

   double add(double x, double y) {
       return math.add(x, y);
   }
   
   double sub(double x, double y) {
       return math.sub(x, y);
   }
   
   double mul(double x, double y) {
       return math.mul(x, y);
   }
   
   double div(double x, double y) {
       return math.div(x, y);
   }
   

private:

   Math math;

};

  1. include <iostream>

using std::cout; using std::endl;

int main() {

   // Create math proxy
   MathProxy p;
   
   // Do the math
   cout << "4 + 2 = " << p.add(4, 2) << endl;
   cout << "4 - 2 = " << p.sub(4, 2) << endl;
   cout << "4 * 2 = " << p.mul(4, 2) << endl;
   cout << "4 / 2 = " << p.div(4, 2) << endl;
   
   return 0;

} </source>

C#

JavaScript

<source lang="javascript"> /* Subject */ function IMath() { this.add = function(x, y) {}; this.sub = function(x, y) {}; }

/* Real Subject */ function RMath() { /* IMath.call(this); // агрегируем IMath, т.к. нативного наследования нет // этот вариант следует использовать вместо прототипирования, // если в IMath имеются приватные переменные, // которые могут быть доступны через геттеры в IMath */ this.add = function(x, y) { return x + y; }; this.sub = function(x, y) { return x - y; }; } RMath.prototype = new IMath(); RMath.prototype.constructor = RMath;

/* Proxy */ function MathProxy() { var math = new RMath();

this.add = function(x, y) { return math.add(x, y); }; this.sub = function(x, y) { return math.sub(x, y); }; }

var test = new MathProxy(); alert(test.add(3, 2)); // 5 alert(test.sub(3, 2)); // 1 </source>

Object Pascal

См. также

Литература



структурные шаблоны проектирования

адаптер | мост | компоновщик | декоратор | фасад | заместитель | приспособленец | Выделение частного класса данных

ar:نمط الوكيل bg:Пълномощно (шаблон) ca:Proxy (patró de disseny) de:Stellvertreter (Entwurfsmuster) en:Proxy pattern es:Proxy (patrón de diseño) fr:Proxy (patron de conception) it:Proxy pattern ja:Proxy パターン lt:Proxy (objektas) pl:Pełnomocnik (wzorzec projektowy) pt:Proxy (padrões de projeto) uk:Замісник (шаблон проектування)

Если вам нравится SbUP.com Сайт, вы можете поддержать его - BTC: bc1qppjcl3c2cyjazy6lepmrv3fh6ke9mxs7zpfky0 , TRC20 и ещё....