8 признаков того, что архитектура вашего проекта уже сломана
СОДЕРЖАНИЕ
Почему архитектурные проблемы замечают поздно
Признак 1 — Любое изменение ломает что-то еще
Признак 2 — Нет возможности покрыть код тестами
Признак 3 — Онбординг нового разработчика занимает больше месяца
Как быстро проверить — задайте новичку вопрос
Признак 4 — Деплой занимает часы и требует ритуалов
Признак 5 — Архитектура данных проекта не отражает бизнес-логику
Признак 6 — Производительность правится хаками, а не архитектурой
Признак 7 — Команда боится трогать отдельные части кода
Признак 8 — Новые фичи реализуются в 3–5 раз медленнее, чем год назад
Таблица: симптом — последствие — степень риска
Архитектура проекта не ломается в один день. Она деградирует постепенно — через компромиссы под дедлайн, через «сделаем нормально потом» и через решения, которые казались разумными два года назад. Проблема в том, что сломанная архитектура не падает с ошибкой. Она просто делает все медленнее, дороже и страшнее.
Ниже — 8 конкретных признаков, по которым можно диагностировать состояние системы. Не абстрактные «плохой код» и «отсутствие документации», а поведенческие симптомы, которые можно наблюдать прямо сейчас.
Почему архитектурные проблемы замечают поздно
Баг виден сразу: что-то упало, пользователь пожаловался, мониторинг сработал. Архитектурный долг не виден — он накапливается в решениях, которые «работают, но не очень». Команда привыкает к медленным деплоям, к тому что «лучше не трогать модуль X», к онбордингу, который занимает полтора месяца.
К моменту, когда проблема становится очевидной, она уже стоит дорого. По данным McKinsey (2022), технический долг составляет в среднем 20–40% от стоимости IT-активов компаний, а его обслуживание съедает до 10–15% бюджета разработки. Архитектурные проблемы — самая дорогая часть этого долга.
Признак 1 — Любое изменение ломает что-то еще
Это самый надежный индикатор. Поменяли название поля в таблице users — сломалось три сервиса, которые, казалось бы, вообще не работают с пользователями. Добавили параметр в метод — упали тесты в модуле, который писали год назад.
За этим стоит высокая связность (tight coupling): компоненты системы знают слишком много друг о друге. В хорошей архитектуре модули взаимодействуют через четкие интерфейсы и не зависят от внутренней реализации соседа. Когда этого нет — изменение в одном месте расходится волнами по всей кодовой базе.
Практический тест: попросите разработчика изменить одну небольшую вещь и посчитайте, сколько файлов он откроет. Больше 5–7 при локальном изменении — повод задуматься.
Признак 2 — Нет возможности покрыть код тестами
Тесты пишутся легко только на хорошей архитектуре. Если для написания юнит-теста к одному методу нужно поднять базу данных, запустить два внешних сервиса и замокать восемь зависимостей — это не проблема тестов. Это архитектура сообщает, что модуль не изолирован.
Хороший признак тестируемости: можно взять любой класс или функцию, передать ей входные данные и проверить результат — без побочных эффектов и внешних зависимостей. Если это невозможно, логика размазана там, где ее не должно быть.
Низкое тестовое покрытие само по себе еще не диагноз — иногда команда просто не писала тесты. Диагноз — когда написать тест физически сложно. Это разные вещи.
Признак 3 — Онбординг нового разработчика занимает больше месяца
Хорошая архитектура данных проекта читается. Если новый человек может за день-два понять, где живет бизнес-логика, как данные движутся через систему и почему принято именно такое решение — архитектура работает. Если через три недели он все еще задает вопросы «а почему здесь так?» — нет.
Долгий онбординг — симптом нескольких вещей сразу: документация отстала от реальности (или ее нет), логика размазана по неожиданным местам, неймингоконвенций нет или они не соблюдаются. Все это — признаки деградации архитектурного качества, а не плохой памяти нового разработчика.
Как быстро проверить — задайте новичку вопрос
Попросите человека, который работает в проекте меньше двух недель, найти, где обрабатывается конкретный бизнес-сценарий — например, «где происходит расчет скидки». Если он находит это за 15 минут — архитектура читается. Если нет — система не говорит сама о себе.
Признак 4 — Деплой занимает часы и требует ритуалов
Когда процесс выкатки — это ручная последовательность из 12–20 шагов, которую знает один-два человека и которая периодически «не работает по непонятным причинам» — архитектура не поддерживает автоматизацию. CI/CD не настраивается поверх любого кода. Для него нужна предсказуемая, детерминированная система.
Симптомы этого признака:
- деплой нельзя запустить в любое время — есть «окна» и «запрещенные дни»
- после каждого деплоя проверяется вручную список из N пунктов
- откат к предыдущей версии занимает больше часа
- деплой одного сервиса требует координации с тремя командами
Если хотя бы два пункта совпали — это уже сигнал.
Признак 5 — Архитектура данных проекта не отражает бизнес-логику
Таблица называется user_data, но хранит заказы. Статус заказа вычисляется из комбинации трех полей в двух разных таблицах. Чтобы понять, активен ли пользователь, нужно написать запрос на 40 строк с четырьмя JOIN-ами.
Это классический признак расхождения между доменной моделью и моделью данных. Хорошая архитектура данных проекта — когда схема БД примерно соответствует языку бизнеса: сущности называются так же, как их называют аналитики и продакты, а правила — одно место, а не пять.
Когда этого нет, каждый новый разработчик строит в голове свою ментальную карту системы. Карты у всех разные. Это источник багов, которые невозможно предсказать.
Признак 6 — Производительность правится хаками, а не архитектурой
Запросы медленные — добавили кеш везде. Кеши устаревают непредсказуемо — добавили инвалидацию, которая работает «почти всегда». База перегружена — денормализовали несколько таблиц без общей схемы. Через год никто не понимает, почему данные в трех местах разные.
Патчи поверх патчей — это не оптимизация, это симптом. В хорошей архитектуре перформанс-решения принимаются системно: где кешировать и почему, как инвалидировать, какие запросы должны быть быстрыми по природе системы. Когда этого плана нет — каждый «фикс» создает два новых ограничения.
Признак 7 — Команда боится трогать отдельные части кода
«Не трогай payment.service.js — там все упадет». «Лучше не менять эту функцию — никто не знает, кто ее вызывает». Если в проекте есть такие места — а они есть почти в каждом проекте старше двух лет — это не проблема конкретного файла. Это симптом архитектурного страха.
Страшные места возникают там, где нет изоляции, нет тестов и нет документации одновременно. Они перестают развиваться, накапливают все больше костылей и в итоге становятся узким местом всей системы — при том что команда сознательно обходит их стороной.
Косвенный показатель: если спросить команду «какой модуль вы меньше всего хотите трогать?» — и все назовут одно и то же место — это оно.
Признак 8 — Новые фичи реализуются в 3–5 раз медленнее, чем год назад
Это самый измеримый признак из всех. Velocity команды падает — а команда не уменьшилась, задачи не стали сложнее. Просто каждая новая фича требует все больше времени на «разобраться как это работает», «не сломать существующее» и «протестировать вручную, потому что автотестов нет».
Если вы ведете метрики (story points, cycle time, lead time) — посмотрите на тренд за 12 месяцев. Падение производительности без роста команды или резкого усложнения задач — прямой индикатор архитектурного торможения.
Отсутствие метрик само по себе тоже симптом, но другой истории.
Таблица: симптом — последствие — степень риска
|
Признак |
Последствие |
Риск |
|
Любое изменение что-то ломает |
Высокая стоимость любой правки; рост страха изменений |
Высокий |
|
Невозможно написать тест |
Баги в продакшне не выявляются до релиза |
Высокий |
|
Онбординг > 1 месяца |
Медленный найм, высокая зависимость от ключевых людей |
Средний |
|
Деплой занимает часы |
Медленный цикл обратной связи; риск долгих простоев |
Средний–высокий |
|
Данные не отражают бизнес |
Баги в бизнес-логике; сложность поддержки отчетности |
Высокий |
|
Перформанс правится хаками |
Непредсказуемое поведение под нагрузкой; рост tech debt |
Средний–высокий |
|
Страшные модули в коде |
Ключевые части системы не развиваются; риск критических сбоев |
Высокий |
|
Velocity упала в 3–5 раз |
Прямые потери выручки; выгорание команды |
Критический |
Что делать, если нашли 3 и более признака
Первый инстинкт — переписать все с нуля. Почти всегда это ошибка. Переписывание убивает функциональность, которая «просто работала» и о которой никто не помнит, занимает вдвое больше запланированного времени и дает ту же архитектуру, только свежую — если команда не изменила подход.
Рабочий путь — поэтапный архитектурный рефакторинг:
- Аудит. Зафиксируйте все 8 признаков применительно к вашей системе. Какие есть, какие нет, где они проявляются сильнее всего. Это карта проблемы.
- Изоляция критических зон. Определите модули с наибольшим риском (страшные места + высокая связность). Их трогать последними — сначала стабилизировать периметр.
- Покрытие тестами перед изменениями. Прежде чем рефакторить модуль — покрыть его интеграционными тестами на текущее поведение. Это страховка, которая позволяет двигаться быстрее.
- Strangler Fig Pattern. Новая функциональность пишется по новым принципам, старая остается работать. Постепенно старый код «душится» новым. Это стандартный подход для больших легаси-систем.
- Метрики до и после. Без измерений непонятно, движетесь ли вы в правильную сторону. Cycle time, покрытие тестами, время деплоя, время онбординга — хотя бы четыре метрики.
FAQ — частые вопросы об архитектурных проблемах
Сколько признаков из восьми — это уже критично?
Три и больше — повод провести архитектурный аудит. Пять и больше — риск, который влияет на бизнес прямо сейчас, даже если это еще не заметно в выручке. Все восемь встречаются в системах, которые существуют 5–10 лет без рефакторинга.
Можно ли предотвратить архитектурный долг?
Полностью — нет. Требования меняются, технологии устаревают, команды ротируются. Но темп накопления долга можно контролировать: регулярные ревью архитектуры, ADR (Architecture Decision Records), выделенное время на рефакторинг в каждом спринте.
Насколько переписать с нуля хуже рефакторинга?
Джоэл Спольски назвал полное переписывание «худшей стратегической ошибкой в разработке ПО» еще в 2000 году — и это не утратило актуальности. Переписывание занимает 2–3 года вместо запланированного одного, замораживает разработку новых фич и в большинстве случаев воспроизводит те же архитектурные ошибки, только свежим кодом.
Как убедить бизнес выделить время на архитектурный рефакторинг?
Переводите в деньги. Если velocity упала на 40% за год — это 40% потерянной производительности команды. Если деплой занимает 3 часа вместо 10 минут — это конкретные деньги за рабочее время. Цифры работают лучше, чем «у нас плохая архитектура».
Что такое Strangler Fig Pattern и когда его применять?
Паттерн из книги Мартина Фаулера: новая система постепенно «обволакивает» старую, берет на себя все больше функций, пока старая не перестает использоваться. Подходит для больших систем, где нельзя остановить все и переписать. Не подходит для очень маленьких модулей — там проще прямой рефакторинг.
Архитектурные проблемы — это всегда вина команды?
Нет. Большинство архитектурных проблем — результат правильных решений в прошлом, которые перестали быть правильными с ростом системы. То, что хорошо работало при 10 000 пользователей, ломается при 1 000 000. Это нормальная эволюция. Вина возникает тогда, когда сигналы игнорировались намеренно.