Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое Decorator
Decorator (Декоратор) — это паттерн проектирования, который позволяет добавлять новые функции к объектам динамически, не изменяя их структуру. В JavaScript это функция, которая обёртывает другую функцию или класс и расширяет его поведение.
Типы декораторов
Функциональные декораторы — оборачивают функции:
function log(fn) {
return function(...args) {
console.log('Вызов', fn.name, 'с аргументами', args);
return fn.apply(this, args);
};
}
function add(a, b) {
return a + b;
}
const loggedAdd = log(add);
loggedAdd(2, 3); // Вывод: Вызов add с аргументами [2, 3]
Классовые декораторы (TypeScript / JavaScript экспериментальный синтаксис):
function Controller(prefix: string) {
return function(constructor) {
constructor.prototype.baseUrl = prefix;
return constructor;
};
}
@Controller('/api/users')
class UserController {
getAll() { /* ... */ }
}
Декораторы методов:
function Memoize(target, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
const cache = new Map();
descriptor.value = function(...args) {
const key = JSON.stringify(args);
if (cache.has(key)) {
return cache.get(key);
}
const result = originalMethod.apply(this, args);
cache.set(key, result);
return result;
};
return descriptor;
}
class Calculator {
@Memoize
expensive(n: number) {
return n * 2; // Вычисляется один раз
}
}
Практические примеры в Node.js
Express middleware как декоратор:
function authenticate(req, res, next) {
if (!req.headers.authorization) {
return res.status(401).json({ error: 'Unauthorized' });
}
next();
}
app.get('/admin', authenticate, (req, res) => {
res.json({ message: 'Admin area' });
});
Декоратор для кэширования в NestJS:
import { CacheKey, Cacheable } from '@nestjs/cache-manager';
@Cacheable()
@CacheKey('users')
@Get('/users')
async getUsers() {
return this.userService.findAll();
}
Собственный декоратор для retry логики:
function retry(attempts = 3) {
return function(target, propertyKey, descriptor) {
const originalMethod = descriptor.value;
descriptor.value = async function(...args) {
for (let i = 0; i < attempts; i++) {
try {
return await originalMethod.apply(this, args);
} catch (error) {
if (i === attempts - 1) throw error;
console.log('Попытка', i + 1, 'не удалась, повторяю...');
}
}
};
return descriptor;
};
}
class ApiClient {
@retry(3)
async fetchData() {
return fetch('https://api.example.com/data');
}
}
Зачем использовать декораторы
Избежать дублирования кода — логирование, валидация, кэширование можно применить ко множеству функций через декоратор.
Разделение ответственности — основная логика отделена от сквозных задач (cross-cutting concerns).
Конфигурируемость — декоратор может принимать параметры.
Читаемость — @log, @Cacheable, @Authenticate явно показывают, что происходит.
Различие от middleware
Middleware — обрабатывает запросы/ответы, работает на уровне HTTP.
Decorator — работает на уровне функции/класса, не привязан к HTTP.
Декораторы — мощный инструмент для расширения функциональности без изменения исходного кода.