Вопрос 9 · Раздел 18

Зачем вообще нужны принципы SOLID?

Принципы SOLID — это не законы физики, а набор эмпирических правил, направленных на борьбу с энтропией программного обеспечения.

Версии по языкам: English Russian Ukrainian

Глубокое погружение (Under the Hood)

Принципы SOLID — это не законы физики, а набор эмпирических правил, направленных на борьбу с энтропией программного обеспечения.

В 2000 году Роберт Мартин описал “признаки гнилого дизайна”, которые SOLID призван устранить:

  1. Rigidity (Жесткость): Система сопротивляется изменениям. Одно маленькое изменение требует правки множества других модулей.
  2. Fragility (Хрупкость): Изменение в одном месте ломает код в совершенно несвязанных местах.
  3. Immobility (Неподвижность): Невозможно переиспользовать часть кода в другой системе, так как она намертво приклеена к текущему контексту.
  4. Viscosity (Вязкость) — когда разработчику проще сделать «хак» или «костыль», чем следовать архитектурному стилю. Пример: чтобы добавить поле, нужно изменить 5 интерфейсов и 10 классов (высокая вязкость). Или просто добавить одно поле (низкая вязкость).

Senior-инсайт: SOLID как экономический инструмент

На уровне Senior важно понимать, что SOLID стоит денег. Создание абстракций, интерфейсов и разделение классов требует больше времени на этапе разработки.

  • Зачем платить? Чтобы снизить Total Cost of Ownership (TCO).
  • Когда это окупается? На долгоживущих проектах (> 6 месяцев), где стоимость поддержки (Maintenance) в разы превышает стоимость написания кода.

SOLID в распределенных системах (Microservices)

Принципы SOLID масштабируются с уровня классов на уровень сервисов:

  • SRP -> Микросервис должен отвечать за одну бизнес-функцию.
  • OCP -> Сервис должен расширяться через новые эндпоинты или события, не ломая старый API.
  • LSP -> Разные реализации одного сервиса (напр. разные версии) должны соблюдать контракт API.
  • ISP -> Клиенты не должны зависеть от полей в JSON, которые они не читают (использование GraphQL или Consumer Driven Contracts).
  • DIP -> Сервисы должны зависеть от стабильных API/Контрактов, а не от деталей реализации других сервисов.

Опасности и крайности

Когда нарушить SOLID осознанно:

  1. Скрипт на 50 строк — SRP/OCP избыточны
  2. Однократная миграция данных — DI/DIP не нужен
  3. Hotfix в продакшене — сначала починить, потом рефакторить
  • YAGNI (You Ain’t Gonna Need It): Часто разработчики строят “аэродромы” из интерфейсов там, где достаточно одного метода. Это порождает “сложность ради сложности”.
  • KISS (Keep It Simple, Stupid): Иногда нарушение SOLID (напр. небольшой switch) делает код понятнее, чем 10 классов-стратегий.

Диагностика и Метрики

Существуют формальные метрики качества кода, основанные на SOLID:

  • LCOM (Lack of Cohesion in Methods): Измеряет, насколько методы класса связаны между собой. Высокий LCOM = нарушение SRP.
  • Afferent/Efferent Coupling: Измеряет входящие и исходящие зависимости модуля. Баланс этих метрик говорит о правильном DIP.
  • Maintainability Index: Интегральный показатель в инструментах типа SonarQube.

Метрики кода:

  • LCOM > 0.8 = проблемы со связностью (методы класса не связаны друг с другом)
  • Afferent Coupling = сколько модулей зависят от этого модуля (входящие зависимости)
  • Efferent Coupling = от скольких модулей зависит этот модуль (исходящие зависимости)
  • Баланс: стабильные модули имеют высокий Afferent, низкий Efferent

Резюме для Senior

  • SOLID снижает частоту каскадных правок при добавлении новой функциональности, но не защищает от изменений в самой доменной модели.
  • Используйте SOLID только там, где ожидаются изменения.
  • Принципы помогают делать код тестируемым (через DI и моки).
  • Не превращайте SOLID в культ; здравый смысл и простота решения (KISS) всегда в приоритете.

🎯 Шпаргалка для интервью

Обязательно знать:

  • SOLID борется с 4 признаками гнилого дизайна: Rigidity, Fragility, Immobility, Viscosity
  • SOLID — экономический инструмент: снижает Total Cost of Ownership на долгоживущих проектах (>6 месяцев)
  • Принципы масштабируются на микросервисы (SRP → один сервис = одна бизнес-функция)
  • LCOM измеряет связность методов, Afferent/Efferent Coupling — баланс зависимостей
  • Осознанное нарушение SOLID: скрипты, одноразовые миграции, hotfix в продакшене
  • YAGNI и KISS — противовесы over-engineering через SOLID

Частые уточняющие вопросы:

  • Что такое Viscosity (Вязкость)? — Когда разработчику проще сделать «костыль», чем следовать архитектуре
  • Когда SOLID не окупается? — Прототипы, скрипты до 50 строк, одноразовые миграции данных
  • Как SOLID влияет на микросервисы? — SRP → один сервис = одна функция, LSP → версии соблюдают контракт API
  • LCOM > 0.8 что означает? — Проблемы со связностью: методы класса не связаны друг с другом

Красные флаги (НЕ говорить):

  • “SOLID — это законы, их нельзя нарушать” (это эмпирические правила, есть обоснованные исключения)
  • “SOLID делает код идеальным” (может привести к over-engineering и complexity ради complexity)
  • “Нужно применять SOLID ко всему коду” (YAGNI: только там, где ожидаются изменения)

Связанные темы:

  • [[20. Можно ли следовать всем принципам SOLID одновременно]]
  • [[19. Как SOLID принципы помогают при расширении функционала]]
  • [[15. Как SOLID помогает в тестировании кода]]
  • [[22. Какие антипаттерны противоречат SOLID принципам]]