Навіщо взагалі потрібні принципи SOLID?
Принципи SOLID — це не закони фізики, а набір емпіричних правил, спрямованих на боротьбу з ентропією програмного забезпечення.
Глибоке занурення (Under the Hood)
Принципи SOLID — це не закони фізики, а набір емпіричних правил, спрямованих на боротьбу з ентропією програмного забезпечення.
В 2000 році Роберт Мартін описав “ознаки гнилого дизайну”, які SOLID покликаний усунути:
- Rigidity (Жорсткість): Система чинить опір змінам. Одна маленька зміна вимагає правки багатьох інших модулів.
- Fragility (Крихкість): Зміна в одному місці ламає код в зовсім не пов’язаних місцях.
- Immobility (Нерухомість): Неможливо перевикористати частину коду в іншій системі, оскільки вона намертво приклеєна до поточного контексту.
- 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 свідомо:
- Скрипт на 50 рядків — SRP/OCP надмірні
- Одноразова міграція даних — DI/DIP не потрібен
- 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]]