Питання 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]]