Skip to content

Instantly share code, notes, and snippets.

@DmitriiNazimov
Last active April 25, 2024 15:24
Show Gist options
  • Save DmitriiNazimov/75f03a8f9782039ac64d42a9c104c7ed to your computer and use it in GitHub Desktop.
Save DmitriiNazimov/75f03a8f9782039ac64d42a9c104c7ed to your computer and use it in GitHub Desktop.
[JS ES6 Паттерн ЗАМЕСТИТЕЛЬ (proxy)] #js #ES6 #ООП Паттерны#
/**
*
* ПАТТЕРН ЗАМЕСТИТЕЛЬ (proxy)
* Предоставляет суррогатный объект, управляющий доступом к другому объекту.
*
* Заместитель это обертка, которая применяется в следующих случаях:
* 1. Ленивая инициализация (виртуальный прокси). Когда у вас есть тяжёлый объект,
* грузящий данные из файловой системы или базы данных.
* 2. Защита доступа (защищающий прокси). Когда в программе есть разные типы пользователей, и вам хочется
* защищать объект от неавторизованного доступа. Прокси может проверять доступ при каждом вызове и передавать
* выполнение служебному объекту, если доступ разрешён.
* 3. Локальный запуск сервиса (удалённый прокси). Когда настоящий сервисный объект находится на удалённом сервере. Мы пишем код, который получает вызов
метода, каким-то образом передает его по сети и вызывает такой же метод удаленного объекта.
* В этом случае заместитель транслирует запросы клиента в вызовы по сети в протоколе, понятном удалённому сервису.
* 4. Логирование запросов (логирующий прокси). Когда требуется хранить историю обращений к сервисному объекту.
* 5. Кеширование объектов («умная» ссылка). Когда нужно кешировать результаты запросов клиентов и управлять
* их жизненным циклом.
*/
// ПЕРВЫЙ ВАРИАНТ
// При такой реализации непонятно в чем отличие от декоратора
class Subject {
constructor() {
}
Request (){
}
}
class RealSubject extends Subject {
constructor() {
super()
console.log('RealSubject created')
}
Request (){
console.log('RealSubject handles request')
}
}
class Proxy extends Subject {
constructor() {
super()
console.log('Proxy created')
}
Request (){
this.realSubject = new RealSubject();
console.log('something another - обертка');
this.realSubject.Request();
}
}
function init_Proxy() {
var proxy = new Proxy()
proxy.Request()
}
init_Proxy();
// ВТОРОЙ ВАРИАНТ
// Здесь ярко выраженное управление доступом к объекту через proxy (Security)
/*
Door interface :
open()
close()
*/
class LabDoor {
open() {
console.log('Opening lab door')
}
close() {
console.log('Closing the lab door')
}
}
class Security {
constructor(door) {
this.door = door
}
open(password) {
if (this.authenticate(password)) {
this.door.open()
} else {
console.log('Big no! It ain\'t possible.')
}
}
authenticate(password) {
return password === 'ecr@t'
}
close() {
this.door.close()
}
}
const door = new Security(new LabDoor())
door.open('invalid') // Big no! It ain't possible.
door.open('ecr@t') // Opening lab door
door.close() // Closing lab door
// ТРЕТИЙ ВАРИАНТ
// Здесь задействован синтаксис ES6 + кэширование через proxy
// Target
function networkFetch(url) {
return `${url} - Response from network`;
}
// Proxy
// ES6 Proxy API = new Proxy(target, handler);
const cache = [];
const proxiedNetworkFetch = new Proxy(networkFetch, {
apply(target, thisArg, args) {
const urlParam = args[0];
if (cache.includes(urlParam)) {
return `${urlParam} - Response from cache`;
} else {
cache.push(urlParam);
return Reflect.apply(target, thisArg, args);
}
},
});
// usage
console.log(proxiedNetworkFetch('dogPic.jpg')); // 'dogPic.jpg - Response from network'
console.log(proxiedNetworkFetch('dogPic.jpg')); // 'dogPic.jpg - Response from cache'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment