Пастка передчасних абстракцій: як сліпе наслідування Clean Architecture створює бюрократичний код і гальмує продукт
Кожен розробник, прочитавши класичні книги про патерни проектування, чисту архітектуру та принципи SOLID, переживає період нестримного бажання застосувати всі ці знання в першому ж робочому завданні. Замість того, щоб написати простий ендпоінт збереження форми на 20 рядків, інженер створює фабрики фабрик, інтерфейси з єдиною реалізацією, окремі DTO для кожного запиту та нескінченні шари маперів.
У результаті виникає явище Over-engineering (надлишкове ускладнення). Код стає настільки «чистим» і фрагментованим, що для розуміння банальної операції реєстрації користувача потрібно відкрити 10 різних вкладок у редакторі, а додавання одного поля в базу даних вимагає внесення правок у пів дюжини архітектурних шарів. Розглянемо, чому простота важливіша за абстракції та як писати код, який допомагає бізнесу, а не заважає йому.
1. Синдром «12 файлів для однієї правки»
Головний симптом хворої архітектури — коли складність самої системи у багато разів перевищує складність бізнес-задачі, яку вона вирішує:
-
Непотрібні інтерфейси (Interface Bloat): Створення інтерфейсу
UserServiceInterfaceдля класуUserService, коли в проекті гарантовано ніколи не буде другої реалізації цього сервісу — це чистий шум, який подвоює кількість файлів і ускладнює навігацію в IDE. -
Транзитні шари (Pass-Through Layers): Коли контролер викликає сервіс, сервіс викликає UseCase, UseCase викликає Repository, а репозиторій просто виконує банальний
find(), не додаючи жодної бізнес-логіки. Дані просто перекладаються з однієї обгортки в іншу. - Втрата локальності контексту: Щоб зрозуміти, як розраховується сума знижки, розробник змушений стрибати по ланцюжку з п'яти папок замість того, щоб побачити весь розрахунок в одному місці.
Золоте правило Сенді Метц
«Дублювання коду обходиться бізнесу в рази дешевше, ніж неправильна абстракція». Спробувавши об'єднати два візуально схожі блоки коду в один універсальний клас занадто рано, ви прирікаєте команду на створення монструозних функцій із десятками прапорців if/else у майбутньому.
2. Пастка фанатичного дотримання DRY
Принцип DRY (Don't Repeat Yourself) є найчастіше неправильно зрозумілим правилом серед молодших і середніх розробників:
- Випадковий збіг проти спільної суті. Два фрагменти коду можуть виглядати однаково сьогодні лише випадково. Наприклад, логіка перевірки пошти клієнта магазину та пошти адміністратора входу. Якщо об'єднати їх у спільний хелпер, перша ж зміна вимог безпеки для адміністраторів змусить вас ламати логіку для звичайних клієнтів.
- Нездорова зв'язаність (Tight Coupling). Прагнучи винести кожні три повторювані рядки в спільний модуль, розробники невидимими нитками зв'язують між собою абсолютно незалежні частини бізнесу. Зміна тарифного плану раптово ламає модуль відправки SMS-повідомлень.
- Коли копіпаста рятує архітектуру. Залишити два схожі блоки коду в різних доменах незалежними — це правильне інженерне рішення, яке дозволяє обом модулям еволюціонувати з власною швидкістю без страху зламати сусіда.
3. Прагматичний підхід: архітектура за потребою (YAGNI)
Принцип YAGNI (You Aren't Gonna Need It) рятує проекти від самозакоханого ускладнення. Як будувати код раціонально:
- Починайте з прямолінійного коду: На етапі створення нової функції пишіть код прямо в контролері або обробнику маршруту. Якщо код поміщається на один екран і легко читається зверху вниз — йому не потрібні три додаткові сервісні шари.
- Правило трьох повторів (Rule of Three): Не створюйте узагальнену абстракцію, поки не побачите одну й ту саму бізнес-потребу, реалізовану в трьох різних місцях. Лише тоді ви будете знати справжні спільні риси, а не вигадані.
- Відкладене проектування: Справжня гнучкість системи полягає не в наявності десятків інтерфейсів «про запас на майбутнє», а в тому, щоб код залишався настільки простим, щоб будь-який розробник міг переписати або винести його за 15 хвилин, коли ця потреба реально настане.
Підсумок
Зрілість інженера визначається не кількістю використаних патернів Банди чотирьох (GoF), а здатністю вирішити задачу найпростішим і найбільш підтримуваним способом. Архітектура повинна слугувати прискорювачем бізнесу, а не бюрократичною перешкодою. Пишіть простий, зрозумілий і прямолінійний код сьогодні — і команда буде вдячна вам щоразу, коли відкриватиме репозиторій.