Что такое принцип открытости/закрытости (OCP) в контексте разработки на Node.js?

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

Ответ

Принцип открытости/закрытости (Open/Closed Principle, OCP) — второй принцип SOLID. Он гласит: «Программные сущности (классы, модули, функции) должны быть открыты для расширения, но закрыты для модификации».

Суть принципа: Поведение модуля должно расширяться без необходимости изменять его исходный код. Это достигается за счет использования абстракций (интерфейсов) и композиции.

Практический пример в Node.js: Допустим, у нас есть сервис уведомлений, который изначально отправляет только email.

Нарушение OCP: При добавлении SMS нужно менять существующий класс.

class NotificationService {
  send(message, type) {
    if (type === 'email') {
      // логика отправки email
    } else if (type === 'sms') { // МОДИФИКАЦИЯ! Добавили новую ветку
      // логика отправки SMS
    }
  }
}

Соблюдение OCP: Определяем абстракцию (стратегию) и расширяем функциональность новыми классами.

// Абстракция (интерфейс)
class NotificationSender {
  send(message) {}
}

// Конкретные реализации
class EmailSender extends NotificationSender {
  send(message) {
    console.log(`Sending email: ${message}`);
    // Реальная логика отправки email
  }
}

class SmsSender extends NotificationSender {
  send(message) {
    console.log(`Sending SMS: ${message}`);
    // Реальная логика отправки SMS
  }
}

// Сервис закрыт для модификации, но открыт для расширения
class NotificationService {
  constructor(sender) {
    this.sender = sender;
  }
  notify(message) {
    this.sender.send(message);
  }
}

// Использование
const emailService = new NotificationService(new EmailSender());
emailService.notify('Hello via Email!');

const smsService = new NotificationService(new SmsSender()); // РАСШИРЕНИЕ!
smsService.notify('Hello via SMS!');

Итог: Следование OCP в Node.js-проектах, часто через паттерны вроде Стратегия или использование DI (Dependency Injection), делает код более устойчивым к изменениям, тестируемым и удобным для поддержки.