Паттерн Strategy позволяет определять семейство алгоритмов, инкапсулировать каждый из них и делать их взаимозаменяемыми. Это особенно полезно в Node.js для сценариев, где требуется гибкость в выборе поведения во время выполнения.
Самый простой способ реализовать Strategy в JavaScript — использовать объект с набором функций:
const strategies = {
add: (a, b) => a + b,
subtract: (a, b) => a - b,
multiply: (a, b) => a * b,
divide: (a, b) => a / b
};
function calculate(strategyName, a, b) {
if (!strategies[strategyName]) {
throw new Error(`Unknown strategy: ${strategyName}`);
}
return strategies[strategyName](a, b);
}
// Использование
console.log(calculate('add', 5, 3)); // 8
console.log(calculate('multiply', 5, 3)); // 15
Для более сложных сценариев можно использовать классы:
class PaymentStrategy {
pay(amount) {
throw new Error('Method not implemented');
}
}
class CreditCardStrategy extends PaymentStrategy {
pay(amount) {
console.log(`Paying ${amount} using Credit Card`);
// Логика обработки кредитной карты
}
}
class PayPalStrategy extends PaymentStrategy {
pay(amount) {
console.log(`Paying ${amount} using PayPal`);
// Логика PayPal
}
}
class CryptoStrategy extends PaymentStrategy {
pay(amount) {
console.log(`Paying ${amount} using Cryptocurrency`);
// Логика криптоплатежа
}
}
class PaymentProcessor {
constructor() {
this.strategy = null;
}
setStrategy(strategy) {
this.strategy = strategy;
}
processPayment(amount) {
if (!this.strategy) {
throw new Error('Payment strategy not set');
}
this.strategy.pay(amount);
}
}
// Использование
const processor = new PaymentProcessor();
processor.setStrategy(new CreditCardStrategy());
processor.processPayment(100);
processor.setStrategy(new PayPalStrategy());
processor.processPayment(200);
const dbStrategies = {
mongodb: require('./mongodb-adapter'),
postgres: require('./postgres-adapter'),
mysql: require('./mysql-adapter')
};
function getDatabaseAdapter(dbType) {
return dbStrategies[dbType] || dbStrategies.mongodb; // fallback
}
const dbAdapter = getDatabaseAdapter(process.env.DB_TYPE);
const logStrategies = {
console: message => console.log(message),
file: message => require('fs').appendFileSync('app.log', message + '\n'),
remote: message => fetch('https://log-service.com', { method: 'POST', body: message })
};
function log(strategy, message) {
logStrategies[strategy](new Date().toISOString() + ' ' + message);
}
const validationStrategies = {
json: require('./json-validator'),
xml: require('./xml-validator'),
form: require('./form-validator')
};
function validateRequest(req, strategyName) {
const validator = validationStrategies[strategyName];
return validator.validate(req);
}
const cacheStrategies = {
memory: require('./memory-cache'),
redis: require('./redis-cache'),
memcached: require('./memcached-cache')
};
function getCacheStrategy(strategyName) {
return cacheStrategies[strategyName] || cacheStrategies.memory;
}
В JavaScript/Node.js паттерн Strategy проще всего реализовать через объект с функциями или набор классов с общим интерфейсом. Этот паттерн особенно полезен в Node.js для обработки запросов, работы с разными СУБД, кеширования и логирования, где требуется гибкость в выборе поведения.