Ответ
Шаблонный метод (Template Method) относится к категории поведенческих паттернов проектирования.
Суть паттерна: Он определяет "скелет" алгоритма в базовом классе, оставляя реализацию некоторых шагов подклассам. Это позволяет подклассам переопределять отдельные шаги алгоритма, не меняя его общей структуры.
Пример реализации на TypeScript/Node.js:
Допустим, у нас есть базовый класс для обработки данных, где общий процесс фиксирован, но шаги извлечения и сохранения данных могут различаться.
abstract class DataProcessor {
// Это и есть ШАБЛОННЫЙ МЕТОД.
public process(): void {
const data = this.extractData();
const transformedData = this.transform(data);
this.save(transformedData);
this.logCompletion();
}
// Шаги, которые должны быть реализованы подклассами.
protected abstract extractData(): any;
protected abstract save(data: any): void;
// Шаг с реализацией по умолчанию (хуки).
protected transform(data: any): any {
console.log('Transforming data...');
return data; // Базовая трансформация
}
protected logCompletion(): void {
console.log('Processing completed.');
}
}
// Конкретная реализация для работы с файловой системой.
class FileDataProcessor extends DataProcessor {
protected extractData(): any {
console.log('Extracting data from file...');
return { fileContent: 'sample data' };
}
protected save(data: any): void {
console.log(`Saving data to a new file: ${JSON.stringify(data)}`);
}
// Можно переопределить и хук, если нужно.
protected transform(data: any): any {
const transformed = super.transform(data);
transformed.processedBy = 'FileProcessor';
return transformed;
}
}
// Использование
const processor = new FileDataProcessor();
processor.process();
Где применяется в Node.js экосистеме: Этот паттерн часто лежит в основе классов фреймворков, например, в middleware-цепочках или в абстрактных классах для стратегий аутентификации, где общий поток определен, а детали — реализуются разработчиком.
Ответ 18+ 🔞
Да ты посмотри, какой прикольный паттерн! Шаблонный метод, ёпта. Это когда у тебя есть какой-то процесс, алгоритм, и он как железная дорога: рельсы уже проложены, поезд едет по одному маршруту, но на станциях могут быть разные вокзалы, понимаешь?
В чём соль, блядь: Берёшь базовый класс и говоришь: «Слушай, дружище, вот общий план операции. Мы делаем раз, два, три. Но пункты «раз» и «три» — это твои проблемы, реализуй как хочешь. А пункт «два» — у меня уже есть нормальная базовая версия, но если захочешь — можешь и её переписать». И подклассы уже сами решают, как им выковыривать данные или куда их пихать. Общая структура — неприкосновенна, это святое. Волнение ебать, как всё продумано!
Смотри на примере, чувак. Допустим, у нас класс для обработки данных. Вечный сценарий.
abstract class DataProcessor {
// Это и есть тот самый ШАБЛОННЫЙ МЕТОД, каркас.
public process(): void {
const data = this.extractData(); // Шаг 1: Вытащить (абстрактный)
const transformedData = this.transform(data); // Шаг 2: Преобразовать (можно переопределить)
this.save(transformedData); // Шаг 3: Сохранить (абстрактный)
this.logCompletion(); // Шаг 4: Лог (базовый)
}
// Вот эти два метода — дырки, которые надо заткнуть. Абстрактные, ёбана!
protected abstract extractData(): any;
protected abstract save(data: any): void;
// А это — хук. Есть базовая реализация, но если надо — впендюрь свою.
protected transform(data: any): any {
console.log('Transforming data...');
return data; // Просто возвращает как есть
}
// И это тоже хук, но его обычно не трогают.
protected logCompletion(): void {
console.log('Processing completed.');
}
}
// А вот конкретный чувак, который работает с файлами.
class FileDataProcessor extends DataProcessor {
protected extractData(): any {
console.log('Extracting data from file...');
return { fileContent: 'sample data' };
}
protected save(data: any): void {
console.log(`Saving data to a new file: ${JSON.stringify(data)}`);
}
// Можешь и хук перебить, если не нравится как работает.
protected transform(data: any): any {
const transformed = super.transform(data); // Сначала делаем как у родителя
transformed.processedBy = 'FileProcessor'; // А потом своё г*** добавляем
return transformed;
}
}
// Используем, бля!
const processor = new FileDataProcessor();
processor.process();
Где это в Node.js пригождается? Да везде, ёклмн! Все эти фреймворки на этом стоят. Тот же Express — у него middleware цепочка это по сути шаблонный метод: запрос прошёл через общий конвейер, а что делать на каждом этапе — твои заморочки. Или взять абстрактные классы для стратегий — общий поток авторизации описан, а как именно проверять логин-пароль или JWT-токен — это уже твоя манда с ушами. Удивление пиздец, как часто этот паттерн под капотом торчит, а многие его и не замечают.