Паттерн Proxy (Прокси), теория
Паттерн Proxy (Прокси) применяется к объектам. Прокси — это специальная прослойка между объектом и тем, кто к нему обращается. Эта прослойка может перехватывать и контролировать все взаимодействия с объектом. То есть появляется возможность базовые операции с объектом (get, set, delete…) дополнить нужной логикой, переопределить или вовсе отменить.
На схеме обращение к объекту проходит не напрямую, а через прокси, который уже в свою очередь может выполнить какое-то дополнительное действие в момент вызова (залогировать, проверить «права доступа», дополнить или скорректировать ответ) и затем уже направить запрос непосредственно к объекту:
В JS паттерн Proxy проще всего реализовать с помощью одноимённого объекта в языке — Proxy. Берём обычный объект в JS, создаём для него прокси-объект, получаем возможность перехватывать и дополнять/переопределять операции, совершаемые с объектом:
// Целевой объектconst target = { message1: "hello", message2: "everyone",};
// Прокси-объектconst handler = { get(target, prop) { console.log(`Свойство ${prop} считалось`);
return target[prop]; }, set(target, prop, value) { console.log(`Свойству ${prop} задано значение ${value}`);
target[prop] = value;
return true; },};
// Proxy принимает в параметрах целевой объект// и прокси-объект, который будет «перехватывать» вызовыconst proxiedObj = new Proxy(target, handler);
proxiedObj.message1;// log: Свойство message1 считалось
proxiedObj.message2 = "nobody";// log: Свойству message2 задано значение nobodyКакие юзкейсы есть у Proxy:
- логирование операций, осуществляемых с объектом (отправка аналитики, мониторинг действий…)
- валидация, «встроенная» в объект (перед заданием значения свойству проверяем, соответствует ли значение правилам валидации)
- кеширование результатов операций с объектом или вызовов функции (функция — это тоже объект, её также можно «проксировать»)
- сохранение объекта в персистентное хранилище («мидлваря», синхронизирующая состояние объекта при его изменении с состоянием на сервере или в локальном хранилище)
Но стоит помнить, что добавление «перегрузки» базовым методам объектов имеет свою цену: в зависимости от того кода, который написан внутри «перехватчика», время выполнения операции с объектом неминуемо увеличится. Так что злоупотреблять Proxy не стоит.