В своих предыдущих блогах я исследовал различные шаблоны творческого проектирования, связанные с механизмами создания объектов. Теперь пришло время углубиться в паттерны структурного проектирования, которые фокусируются на том, как объекты и классы компонуются для формирования более крупных структур, сохраняя при этом их гибкость и эффективность. Начнем с шаблона проектирования прокси
Шаблон проектирования «Прокси» — это структурный шаблон проектирования, который предоставляет объект, представляющий другой объект. Он действует как посредник, который контролирует доступ к реальному объекту, добавляя дополнительное поведение, такое как отложенная инициализация, ведение журнала, контроль доступа или кэширование, без изменения кода исходного объекта.
В JavaScript прокси — это встроенные функции, предоставляемые объектом Proxy, которые позволяют вам определять собственное поведение для основных операций, таких как доступ к свойствам, назначение, вызов функций и т. д.
Шаблон «Прокси» особенно полезен, когда:
Представьте, что у вас есть большая картина, которую вы хотите показать своим гостям, но ее вытаскивание из кладовой занимает много времени (потому что она тяжелая и ее переноска требует времени). Вместо того, чтобы каждый раз ждать этого, вы решаете использовать небольшое изображение картины на открытке, чтобы быстро показать им, пока они ждут, пока принесут настоящую картину.
В этой аналогии:
Думайте об агенте по недвижимости как о доверенном лице. Когда вы хотите купить дом, вы не посещаете сразу каждый дом (загружая реальный объект). Вместо этого агент по недвижимости (прокси) сначала показывает вам фотографии и описания. Только когда вы готовы совершить покупку (т. е. когда вы вызываете display()), агент организует посещение дома (загружает реальный объект).
Давайте воспользуемся примером загрузки изображения в веб-приложении, где мы хотим отложить загрузку изображения до тех пор, пока пользователь не запросит его (отложенная загрузка). Прокси-сервер может выступать в качестве заполнителя до тех пор, пока не будет загружено настоящее изображение.
Вот как можно реализовать шаблон проектирования «Прокси» в JavaScript.
// Step 1: The real object class RealImage { constructor(filename) { this.filename = filename; this.loadImageFromDisk(); } loadImageFromDisk() { console.log(`Loading ${this.filename} from disk...`); } display() { console.log(`Displaying ${this.filename}`); } } // Step 2: The proxy object class ProxyImage { constructor(filename) { this.realImage = null; // no real image yet this.filename = filename; } display() { if (this.realImage === null) { // load the real image only when needed this.realImage = new RealImage(this.filename); } this.realImage.display(); // display the real image } } // Step 3: Using the proxy to display the image const image = new ProxyImage("photo.jpg"); image.display(); // Loads and displays the image image.display(); // Just displays the image (already loaded)
Объяснение:
1). Реальное изображение:
2). Прокси-изображение:
3). Использование:
Прокси-сервер ES6 состоит из конструктора прокси, который принимает цель и обработчик в качестве аргументов
const proxy = new Proxy(target, handler)
Здесь target представляет собой объект, к которому применяется прокси, а обработчик – это специальный объект, определяющий поведение прокси.
Объект-обработчик содержит ряд дополнительных методов с предопределенными именами, называемыми методами-ловушками (например, apply,get,set и has), которые автоматически вызываются при выполнении соответствующих операций над экземпляром прокси.
Давайте разберемся в этом, реализовав калькулятор с использованием встроенного прокси
// Step 1: Define the Calculator class with prototype methods class Calculator { constructor() { this.result = 0; } // Prototype method to add numbers add(a, b) { this.result = a b; return this.result; } // Prototype method to subtract numbers subtract(a, b) { this.result = a - b; return this.result; } // Prototype method to multiply numbers multiply(a, b) { this.result = a * b; return this.result; } // Prototype method to divide numbers divide(a, b) { if (b === 0) throw new Error("Division by zero is not allowed."); this.result = a / b; return this.result; } } // Step 2: Create a proxy handler to intercept operations const handler = { // Intercept 'get' operations to ensure access to prototype methods get(target, prop, receiver) { if (prop in target) { console.log(`Accessing property: ${prop}`); return Reflect.get(target, prop, receiver); // Access property safely } else { throw new Error(`Property "${prop}" does not exist.`); } }, // Intercept 'set' operations to prevent mutation set(target, prop, value) { throw new Error(`Cannot modify property "${prop}". The calculator is immutable.`); } }; // Step 3: Create a proxy instance that inherits the Calculator prototype const calculator = new Calculator(); // Original calculator object const proxiedCalculator = new Proxy(calculator, handler); // Proxy wrapping the calculator // Step 4: Use the proxy instance try { console.log(proxiedCalculator.add(5, 3)); // Output: 8 console.log(proxiedCalculator.multiply(4, 2)); // Output: 8 console.log(proxiedCalculator.divide(10, 2)); // Output: 5 // Attempt to access prototype directly through proxy console.log(proxiedCalculator.__proto__ === Calculator.prototype); // Output: true // Attempt to modify a property (should throw an error) proxiedCalculator.result = 100; // Error: Cannot modify property "result". } catch (error) { console.error(error.message); // Output: Cannot modify property "result". The calculator is immutable. }
Лучшая часть использования прокси:
- Прокси-объект наследует прототип исходного класса Calculator.
- Мутаций можно избежать благодаря установленной ловушке Прокси.
Пояснение Кодекса
1). Наследование прототипа:
2). Обработка getOperations:
3). Предотвращение мутаций:
Ловушка set выдает ошибку при каждой попытке изменить какое-либо свойство целевого объекта. Это обеспечивает неизменность.
4). Использование методов прототипа через прокси:
Прокси обеспечивает доступ к таким методам, как сложение, вычитание, умножение и деление, все из которых определены в прототипе исходного объекта.
Ключевые моменты, на которые следует обратить внимание:
Если вы зашли так далеко, не забудьте поставить лайк ❤️ и оставить комментарий ниже с любыми вопросами или мыслями. Ваш отзыв очень важен для меня, и мне бы хотелось услышать ваше мнение!
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3