Может показаться, что в современной разработке только и успеваешь, что реагировать на изменения: новые интеграции, обновленные бизнес-правила, смена тех��ологического стека. В итоге команды тратят недели на задачи, которые должны решаться днями, а каждое новое требование встречается с сопротивлением. Но что если существует подход, который превращает постоянные изменения из головной боли в конкурентное преимущество? В этой статье мы говорим о проектировании на основе нестабильности — архитектурной парадигме, которая позволяет системам становиться лучше с каждым изменением. А если вы хотите сразу перейти к практической части, читайте мою вторую статью.

Не стоит создавать лишние ограничения на этапе проектирования ПО
Не стоит создавать лишние ограничения на этапе проектирования ПО

«Хорошая архитектура предвидит изменчивость и защищается от нестабильности через четкое разделение ответственности» 

Джуэл Леве, «Совершенный софт»

Привет, Хабр! Меня зовут Игорь Стряпков, и я — ведущий архитектор в Cloud X. В работе мы постоянно сталкиваемся с тем, что современные системы программного обеспечения все больше живут в условиях постоянных изменений: новые требования, изменяющиеся бизнес‑правила, новые технологии, расширение функциональности. Однако большинство архитектурных подходов, таких как функциональная декомпозиция, не учитывают эту реальность. В результате команды сталкиваются с высокой стоимостью изменений и непредсказуемыми срывами сроков.

Но мы на своем опыте убедились в том, что разработка в условиях нестабильности — это подход, который признает изменчивость требований как данность и предлагает систематические методы создания архитектур, способных эволюционировать вместе с бизнесом. Другими словами, на сегодня меняющиеся требования — это не отклонение от нормы, а естественное состояние разработки. И поэтому я хотел бы подробнее поговорить о том, как превратить постоянные изменения из угрозы в конкурентное преимущество.

Почему традиционные подходы терпят неудачу?

Для начала давайте поговорим о ловушке функциональной декомпозиции, одного из наиболее популярных подходов в разработке 

Функциональная декомпозиция — это интуитивный способ мышления, при котором мы разбиваем задачу на последовательные шаги или компоненты, основанные на действиях. На бумаге это выглядит логично. Однако в динамичном мире разработки этот подход создает архитектуру, которая сопротивляется изменениям.

Проблема в том, что программы живут годами, а требования меняются ежемесячно. Все это приводит к хорошо знакомым проблемам:

  • Жесткие связи: Модули зависят друг от друга, делая систему хрупкой.

  • Эффект домино: Изменения в одной части системы неожиданно "ломают" другие.

  • Инертность: Невозможно быстро внедрить новое решение без переписывания большого объема кода.

Классический пример такого подхода – функциональная архитектура. Джуэл Леве в книге "Совершенный софт" приводит блестящую аналогию разработки ПО с проектированием дома. Представьте, что архитектор решил применить функциональную декомпозицию и спроектировал здание исходя из его назначения::

  • Спальная зона

  • Обеденная зона

  • Зона для приготовления пищи

  • Гостевой блок

На первый взгляд, все логично. Но что произойдет, если требования изменятся? Например, в семье родился ребенок, и теперь нужно две спальные зоны. Или вы решили работать из дома и вам нужен кабинет.

Такая перепланировка будет напоминать реконструкцию с переносом несущих стен. Потому что изначальная архитектура «зашила» изменчивые по своей сути бизнес-требования (кто и как использует комнаты) в саму статичную структуру здания.

Каждое такое изменение требует пересмотра всей последовательности — ведь логика «зашита» в порядок шагов. Вместо гибкой системы вы получаете жёсткий сценарий, где даже мелкая корректировка превращается в полную переработку.

Именно это состояние и называют функциональным хаосом — когда архитектура не поддерживает, а наоборот, активно мешает развитию бизнеса. Добавление новой функциональности становится мучительным процессом переписывания десятков связанных модулей.

Природа изменений в разработке ПО

Изменения — это замечательно, но многие специалисты в течение всей своей карьеры сопротивляются таким изменениям. В требованиях и ТЗ уже могут быть предусмотрены изменения. Например, когда мы начинаем делать MVP, то понима��м, что многое может поменяться. Однако программный код, написанный некорректно, может являться стоппером для изменения (что сильно влияет на развитие продукта, платформы и т.д.). 

Таким образом получается, что требования которые могли бы быть пластичными, получаются совершенно дубовыми и неповоротливыми. За свой карьерный путь я много раз встречал ситуацию, когда на новые изменения системы разработчики с пеной у рта доказывают, что "этот код трогать нельзя, это критический участок!!!" Здесь может быть сказано много умных слов (которые зачастую скрывают некомпетентность), вместо того что бы просто реализовать нужные изменение. В итоге мы получаем требования, которые “могут быть изменимы, но в итоге не могут быть изменимы, просто "потому что не могут”. 

Такие люди стараются довести до максимума соответствие между требованиями и проектировочными решениями. Однако при изменении требований, хорошо это или плохо, их решение также должно измениться. И если из-за этого приходится переписывать его с нуля…значит кто-то плохо подготовился к реальности.

Если же смириться с тем, что мир не статичен, нужно подойти к работе с изменениями системно. Для этого специалисты рекомендуют разделить их на два типа: изменчивость и нестабильность. 

  • Изменчивость — предсказуемые аспекты, которые можно обработать на уровне кода. Например, это может быть смена форматов экспорта отчета – в PDF, Excel, CSV или еще что-то.

  • Нестабильность — источник архитектурного риска, где изменения непредсказуемы. Например, речь может идти про смену основного источника данных (с БД на внешнее API)

«Хорошая архитектура предвидит изменчивость и защищается от нестабильности через четкое разделение ответственности»

Джуэл Леве.

То есть для успешной разработки нам нужно прийти к позиции, что нестабильность — это не ошибка, а особенность реального мира. А наша задача состоит в том, чтобы сделать её контролируемой. 

Проектирование на основе нестабильности

Чтобы внедрить практику проектирования на основе нестабильности вместо вопроса «Что система делает?», необходимо отвечать на вопрос: «Что в системе с наибольшей вероятностью изменится?»

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

Для такого подхода характерно два признака.

  • Во-первых, стабильное ядро (в виде абстракций) определяет контракты, от которых зависят нестабильные технические модули. Это достигается за счет инверсии зависимостей.

  • Во-вторых, благодаря такому разделению, любое изменение в технических реализациях может происходить без изменений в ядре. Новая реализация должна лишь соответствовать установленному стабильному контракту.

Поэтому ключевые принципы проектирования на основе нестабильностей выглядят следующим образом:

  1. Идентификация осей нестабильности — определение областей с высокой вероятностью изменений;

  2. Создание стабильных абстракций для каждой оси нестабильности;

  3. Изоляция нестабильных реализаций в заменяемые модули;

  4. Инверсия зависимостей — от нестабильного к стабильному.

Смена парадигмы проектирования

В примере с домом мы видим жилое пространство, которое может использоваться по-разному — как семейное гнездо, гостевой дом или рабочее пространство. И поэтому, с учетом возможных изменений, важно создавать архитектуру, которая позволяет легко адаптировать назначение помещений под меняющиеся потребности. Однако не стоит впадать в крайности избыточной абстракции — вряд ли жилое здание будут полностью перепрофилировать в промышленный объект. Но для него вполне допустима эволюция из частного дома в многоквартирный комплекс или офисное здание с сохранением структурной целостности.

И если традиционный подход подразумевает, что мы строим все в соответствии с жестким функциональным планом, четко оборудуя спальню, гостиную, кухню, санузел, то подход на основе нестабильности предлагает нам создать адаптивную систему, которая включает в себя несущий каркас, коммуникационные узлы и модульные помещения, предусматривающие различные сценарии использования.

Такой подход позволяет легко менять назначение комнат без перестройки всего дома — так же, как в программной системе мы можем менять бизнес-логику, не затрагивая архитектурное ядро.

Учитывая нестабильность, мы получаем возможности:

  • Легко трансформировать спальню в кабинет при работе из дома

  • Объединять или разделять помещения при изменении состава семьи

  • Интегрировать новые инженерные системы без перепланировки

  • Масштабировать функциональность от частного дома к многофункциональному комплексу.

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

А что же на практике?

Подводя промежуточный итог можно сказать, что требования современного мира таковы, что от нас все больше и больше требуется гибкости и адаптивности. Поэтому разработка ПО с поправкой на нестабильность требует новых подходов. И если вас заинтересовала эта тема, в следующей статье я подробно рассказываю про выбор осей нестабильности, принципы обратных зависимостей, локализацию изменений на практике и достижение архитектурной устойчивости. Подписывайтесь на блог Cloud X и давайте обсуждать эти и другие важные темы вместе!