Код найма-8
Код найма-8
Код найма-8

Неизбежность эволюции программных систем

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

169 открытий3К показов
Неизбежность эволюции программных систем

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

На самом деле подобная постановка вопроса некорректна. Практически любое решение никогда не бывает финальным, тем более сразу. Об этом пишут многие заслуженные авторы, но самой яркая цитата, пожалуй, закон Голла.

Любая работающая сложная система неизменно оказывается производной простой работающей системы.
Джон ГоллSystemantics (1975)

Позволю себе внести важные уточнения.

  • Простота системы означает не примитивизм, а наличие ограниченного числа взаимодействующих между собой элементов с понятными и прослеживаемыми связями между ними.
  • Сложность системы означает не трудность организации самой системы, а её зрелость, точность модели предметной области.

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

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

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

Такие размышления — не откровение, об этом давно и много говорят. Я лишь хочу подчеркнуть: задача архитектора — не просто принять логичное решение, но и просчитать его развитие. Важно думать на несколько шагов вперёд, сохраняя при этом простоту и гибкость архитектуры как можно дольше. Это, пожалуй, и есть лучший ориентир в выборе времени и уместности тех или иных решений. Каждый шаг должен вести к цели, закладывать основу для следующего и помогать точнее видеть направление движения. Если всё это соблюдается — значит, пора действовать.

Именно с такой перспективы стоит подходить к обоснованию архитектурных решений. Поэтому некоторые «аргументы», о которых пойдёт речь ниже, стоит отбрасывать сразу — несмотря на их комичность, в практике они встречаются до сих пор.

  • Выбор технологии на основе только её популярности. («Так принято в лучших домах!», «Kafka справится с любой задачей» и т.п.)
  • Ориентация на скорость, обоснованная амбициями или ощущениями. («Некогда думать — надо действовать!», «Мир сам себя не захватит!»)
  • Неоправданное и/или преждевременное усложнение. («У меня нет задач, нужно придумать что-то интересненькое», «У меня скучные задачи, нужно добавить драйва», «Я предусмотрел обработчик на случай вторжения инопланетян!» и т.п.)
  • Неоправданное расширение технологического стека. («CV-Driving Development», «Решил попробовать», «Мне так удобней» и т.п.)

Принимая неизбежность эволюционного развития систем, важность гибкости архитектуры на ранних стадиях, а также необходимость постоянной корректировки направления развития (стратегии), люди задают вопрос, почему кто-то начинает не с простых вещей. Почему кто-то сразу начинает с гексагональных архитектур или микросервисов?

Согласен, что иногда это и есть преждевременное усложнение. Однако, если архитектор или разработчик достаточно опытный, он может позволить себе «срезать углы», действуя на опережение. В данном случае он должен осознавать и указывать на все риски подобных действий, в том числе понимать, кто будет поддерживать и сопровождать такой продукт. Тут можно вернуться к метафоре с «космическим кораблём»: нужен ли он на старте, есть ли у вас подходящая команда, инфраструктура, ресурсы?

Я постарался описать тактику принятия решений, которой стараюсь пользоваться в работе. Было бы интересно узнать, как вы справляетесь с соблазнами несвоевременного применения понравившегося решения.

P.s. Если вам интересна данная тематика, присоединяйтесь к моей новостной ленте в Telegram или здесь. Буду рад поделиться опытом. 😉

Следите за новыми постами
Следите за новыми постами по любимым темам
169 открытий3К показов