Коротка відповідь
middleProxy — це патерн, що створює об’єкт‑заместник для контролю доступу до реального об’єкта, часто з додатковою логікою (кешування, авторизація). У TS це просто клас, що реалізує той самий інтерфейс і проксуює виклики: `class Proxy implements Service { constructor(private real: Service) {} call() { /* pre‑logic */ return this.real.call(); }}`
Повне пояснення
1. Що це і навіщо
Proxy (Заместитель) – патерн, що дозволяє створити об’єкт‑заместник, який контролює доступ до реального об’єкта. Застосовується для відкладеного створення, кешування, авторизації, логування тощо.
2. Принцип роботи / алгоритм
Патерн складається з двох ключових ролей: RealSubject (реальний об’єкт) і Proxy. Proxy реалізує той самий інтерфейс, що й RealSubject, і передає виклики до реального об’єкта після виконання додаткових дій. Якщо потрібен lazy‑інстанцювання, Proxy створює RealSubject лише при першому виклику.
3. Реалізація (JS / TS)
- Базова реалізація
interface Service { request(): void; }
class RealService implements Service {
request() { console.log('Real service'); }
}
class ProxyService implements Service {
private real?: RealService;
request() {
if (!this.real) this.real = new RealService();
console.log('Proxy before');
this.real.request();
console.log('Proxy after');
}
}
- Веб‑dev приклад – проксі для API‑запитів з кешуванням
class ApiProxy {
private cache = new Map<string, any>();
async get(url: string) {
if (this.cache.has(url)) return this.cache.get(url);
const res = await fetch(url);
const data = await res.json();
this.cache.set(url, data);
return data;
}
}
- Новачковий приклад – логування
class LoggingProxy implements Service {
constructor(private real: Service) {}
request() { console.log('log'); this.real.request(); }
}
4. Тестування (Jest або Vitest)
test('Proxy defers to real service', () => {
const real = { request: jest.fn() } as Service;
const proxy = new ProxyService(real);
proxy.request();
expect(real.request).toHaveBeenCalled();
});
5. Проблеми та edge cases
- Неправильне використання ролей – Proxy замість RealSubject, що порушує інтерфейс.
- Зайва абстракція – створення Proxy, коли його логіка не потрібна.
- Cyclical dependencies – Proxy залежить від RealSubject, а RealSubject знову звертається до Proxy.
- Плутанина між патернами – змішання Proxy з Decorator, коли треба розширювати функціональність.
- Performance‑пастки – надмірне кешування або зайва обробка в Proxy, що збільшує час відповіді.
6. Оптимізація та продуктивність
Proxy додає один рівень абстракції, що збільшує час виклику на ~1–2 %. Якщо Proxy кешує, це компенсується. Пам’ять використовується лише для об’єкта‑заместника і, при кешуванні, для кешу.
7. Без JS / архітектурні альтернативи
У чистій HTML/CSS можна реалізувати «проксі» через <iframe> або fetch‑обгортку. У бекенді без патерна можна просто викликати функцію‑обгортку, що містить логіку авторизації.
8. Cheatsheet + follow-up
- Cheatsheet:
Proxy → RealSubject, інтерфейс однаковий, додаткова логіка перед/після виклику. - Interview Q: Які типи Proxy існують? (Virtual, Protection, Smart).
- Interview Q: Як уникнути циклічних залежностей у Proxy‑проекті?