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

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

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

Цель

Проблема

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

Решение

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

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

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

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

Плюсы

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

Минусы

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

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

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

Примеры

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);
	}
}

C++

/**
 * "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;
};

#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;
}

C#

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

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 и ещё....