К какому паттерну проектирования относится шаблонный метод (Template Method)?

«К какому паттерну проектирования относится шаблонный метод (Template Method)?» — вопрос из категории Паттерны, который задают на 26% собеседований Node.js Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Шаблонный метод (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-цепочках или в абстрактных классах для стратегий аутентификации, где общий поток определен, а детали — реализуются разработчиком.