Паттерны проектирования в JavaScript: примеры для Node.js

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Паттерны проектирования в JavaScript с примерами для Node.js

Паттерны проектирования — это проверенные решения типовых задач разработки. В JavaScript, особенно в среде Node.js, они помогают создавать масштабируемый, поддерживаемый и переиспользуемый код. В этой статье мы разберём четыре основных паттерна: Singleton, Factory, Observer и Module, с практическими примерами.

1. Паттерн Singleton (Одиночка)

Singleton гарантирует, что класс имеет только один экземпляр, и предоставляет глобальную точку доступа к нему. В Node.js это часто используется для подключения к базе данных или конфигурации приложения.

Реализация Singleton в Node.js

class Database {
  constructor() {
    if (Database.instance) {
      return Database.instance;
    }
    this.connection = null;
    Database.instance = this;
  }

  async connect(uri) {
    // Имитация подключения к БД
    this.connection = `Connected to ${uri}`;
    console.log(this.connection);
  }

  getConnection() {
    return this.connection;
  }
}

// Использование
const db1 = new Database();
const db2 = new Database();

console.log(db1 === db2); // true

db1.connect('mongodb://localhost:27017/myapp');
console.log(db2.getConnection()); // "Connected to mongodb://localhost:27017/myapp"

Когда использовать: Управление пулом соединений, глобальный логгер, кэш-системы.

2. Паттерн Factory (Фабрика)

Factory позволяет создавать объекты без указания конкретного класса. Он централизует логику создания объектов, упрощая поддержку кода.

Реализация Factory для валидаторов

class EmailValidator {
  validate(value) {
    return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
  }
}

class PhoneValidator {
  validate(value) {
    return /^\+?[\d\s\-()]{7,15}$/.test(value);
  }
}

class ValidatorFactory {
  createValidator(type) {
    switch (type) {
      case 'email':
        return new EmailValidator();
      case 'phone':
        return new PhoneValidator();
      default:
        throw new Error('Unknown validator type');
    }
  }
}

// Использование
const factory = new ValidatorFactory();
const emailValidator = factory.createValidator('email');

console.log(emailValidator.validate('test@example.com')); // true
console.log(emailValidator.validate('invalid')); // false

Когда использовать: Создание сложных объектов, работа с разными форматами данных (JSON, XML, YAML), генерация UI-компонентов.

3. Паттерн Observer (Наблюдатель)

Observer создаёт механизм подписки, позволяющий одним объектам (наблюдателям) следить за изменениями в другом объекте (субъекте). В Node.js этот паттерн встроен через класс EventEmitter.

Реализация Observer с EventEmitter

const EventEmitter = require('events');

class NewsPublisher extends EventEmitter {
  publishArticle(title) {
    console.log(`📰 Опубликована статья: ${title}`);
    this.emit('article', { title, date: new Date() });
  }
}

class Subscriber {
  constructor(name) {
    this.name = name;
  }

  receiveArticle(article) {
    console.log(`🔔 ${this.name} получил: "${article.title}"`);
  }
}

// Использование
const publisher = new NewsPublisher();
const subscriber1 = new Subscriber('Анна');
const subscriber2 = new Subscriber('Иван');

publisher.on('article', (data) => subscriber1.receiveArticle(data));
publisher.on('article', (data) => subscriber2.receiveArticle(data));

publisher.publishArticle('Паттерны проектирования в JavaScript');
// Вывод:
// 📰 Опубликована статья: Паттерны проектирования в JavaScript
// 🔔 Анна получил: "Паттерны проектирования в JavaScript"
// 🔔 Иван получил: "Паттерны проектирования в JavaScript"

Когда использовать: Обработка событий, real-time приложения (чаты, уведомления), системы мониторинга.

4. Паттерн Module (Модуль)

Module — один из самых популярных паттернов в JavaScript. Он инкапсулирует приватные данные и методы, предоставляя только публичный API. В Node.js модули реализованы через require и module.exports.

Реализация Module для работы с пользователями

// userManager.js
const users = []; // Приватная переменная

function validateUser(user) {
  return user.name && user.email;
}

module.exports = {
  addUser(user) {
    if (!validateUser(user)) {
      throw new Error('Invalid user data');
    }
    users.push(user);
    return `User ${user.name} added`;
  },

  getUsers() {
    return [...users]; // Возвращаем копию
  },

  findByName(name) {
    return users.find(user => user.name === name) || null;
  },

  get count() {
    return users.length;
  }
};

// Использование в другом файле
const userManager = require('./userManager');

userManager.addUser({ name: 'Алексей', email: 'alex@example.com' });
userManager.addUser({ name: 'Мария', email: 'maria@example.com' });

console.log(userManager.count); // 2
console.log(userManager.getUsers());
// [{ name: 'Алексей', email: 'alex@example.com' }, { name: 'Мария', email: 'maria@example.com' }]

console.log(userManager.findByName('Мария')); // { name: 'Мария', email: 'maria@example.com' }

Когда использовать: Практически любой JavaScript-код. Это основа для организации Node.js приложений.

Сравнение паттернов и рекомендации

Выбор паттерна зависит от конкретной задачи:

  • Singleton — когда нужен ровно один экземпляр (БД, конфиг).
  • Factory — когда создание объектов сложное или зависит от условий.
  • Observer — для событийно-ориентированной архитектуры.
  • Module — для организации кода и сокрытия деталей реализации.

Заключение

Паттерны проектирования — это не догма, а инструменты. Используйте их осознанно, не усложняя код там, где достаточно простого решения. В JavaScript и Node.js особенно популярны модульная система и событийная модель, что делает паттерны Observer и Module естественным выбором для большинства приложений.

Освоив эти четыре паттерна, вы получите прочную базу для дальнейшего изучения более сложных шаблонов, таких как Proxy, Decorator или Strategy. Практикуйтесь на реальных проектах, и паттерны станут вашим надёжным помощником в разработке.

Блоги

Рекомендаций по книгам