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

Итак, без долгих предисловий:

1. Всегда учитывайте контекст

Не создавайте “Сферических коней в вакууме”

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

Примеры:

  • Можно привести много аргументов, почему Rust лучше Java. Но важен контекст. Какие конкретные преимущества Rust актуальны для нашей задачи? Что, если у нас среднестатистическое веб-приложение и при этом вся экосистема построена на Java? Сколько плюсов будет в этом случае?

  • Микросервисная архитектура имеет множество достоинств. Но в нашем случае — действительно ли они нам нужны? Что, если у нас одна команда, низкие нагрузки и высокие требования к транзакционности? Не будут ли микросервисы в этом случае только усложнением и оверхедом?

2. Решайте только реальные проблемы

Не решайте несуществующих проблем (YAGNI)

Не оптимизируйте преждевременно. Как говорил Дональд Кнут, “Преждевременная оптимизация — это корень всех бед”.

Любое решение или архитектура должны быть обоснованы. Мы не решаем проблем, которых у нас нет, будь то усложнение архитектуры ради гипотетических выгод или преждевременная оптимизация работающего кода. Решения должны рождаться из реальных потребностей, а не из желания «сделать красиво» или «как у больших компаний», иначе это просто трата ресурсов.

Это не означает игнорировать будущее. Стратегическое планирование на основе известных или высоковероятных изменений — это не преждевременная оптимизация, а необходимая дальновидность. Ключ к оптимальной системе — это баланс между «не делать лишнего» и «быть готовыми к росту»(про это подробнее в 4 принципе).

Примеры:

  • Решение несуществующей проблемы:

    • Да, Redis может ускорить доступ к данным. Но если база данных и так отвечает за миллисекунды, и нет перегрузки — зачем кэш? Его нужно будет настраивать, инвалидировать, следить за консистентностью. Не создавайте себе лишнюю точку отказа без необходимости.

    • «А вдруг потом у нас появятся графовые зависимости, давайте сразу возьмём Neo4j» — нет. Строить архитектуру на основе возможных, но пока несуществующих требований — ошибка. Делайте просто, пока нет необходимости в сложном.

  • Преждевременная оптимизация:

    У нас есть простая страница, на которой отображаются 100 записей. Запрос к базе выполняется за 20 мс, нагрузка — минимальная, изменений в объёме или модели данных не предвидится. В такой ситуации нет смысла добавлять индексы, выносить агрегации в отдельные сервисы, делать кеширование или писать ручной SQL вместо ORM. Это преждевременная оптимизация, которая усложняет код и увеличивает время разработки.
    Но если мы знаем, что в ближайшее время эта страница станет точкой высокой нагрузки — тогда стоит заранее подумать о производительности и заложить нужные механизмы.

  • Когда это правило не работает:

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

3. В приоритете - простота и поддержка (KISS)

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

Чем сложнее система, тем легче сделать ошибку, тем выше её цена и тем сложнее обучение новых участников команды. 

Примеры:

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

  • Rich Domain Model, Event Sourcing, CQRS — мощные инструменты. Но нужны ли они нам? Если у вас CRUD на 10 эндпоинтов — они будут не решением, а лишним грузом. Используйте такие подходы, когда у вас действительно есть та сложность, ради которой они создавались.

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

4. Взвешивайте компромиссы (трейд-оффы) и держите баланс.

Архитектура — это всегда искусство баланса. Серебрянных пуль не существует. Каждое решение влечёт за собой последствия: мы что-то выигрываем и что-то теряем. Хорошая архитектура — это не «лучшее решение», а наиболее уместное в конкретном контексте, с учётом целей, ограничений и рисков. Про это даже целая книга написана.

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

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

Примеры:

  • CAP-теорема

    В распределённых системах нельзя одновременно обеспечить консистентность, доступность и устойчивость к разделению сети. Нужно выбирать два из трёх. Например, Cassandra делает ставку на доступность и устойчивость, жертвуя строгой консистентностью. А PostgreSQL в режиме репликации может обеспечить консистентность, но при этом становится менее доступным.

  • Скорость разработки vs долгосрочная поддержка

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

5. Проектируйте стратегически для создания эволюционирующей архитектуры

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

Ключ к такой эволюции — это стратегический подход к проектированию, а не тактический.

  • Тактическое решение — это решение задачи "в лоб": сделать ровно то, что требуют, не думая о дизайне и последствиях.

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

Как утверждает Джон Остерхаут в своей книге, тактический подход в средне- и долгосрочной перспективе не ускоряет, а наоборот — тормозит развитие. Стратегический подход, напротив, — это инвестиция в скорость будущих изменений. 

При этом важен баланс: не нужно каждый раз тратить +100% времени на начальный дизайн если в этом нет явной необходимости. Но дисциплинированное выделение хотя-бы 10–30% времени окупается уже через несколько месяцев.

Примеры:

  • У вас есть набор текущих требований.

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

    Во втором случае вы не ограничиваетесь только текущими требованиями: вы общаетесь со стейкхолдерами, выясняете, как продукт может развиваться в ближайшем будущем, и формулируете обоснованные предположения (assumptions) о потенциальных изменениях. На основе этого вы проектируете модульную и расширяемую архитектуру, которая решает текущие задачи и в то же время легко расширяема для поддержки потенциальных изменений.

  • Исключение:

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

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

Заключение

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

Комментарии (11)


  1. 1CUnlimited
    15.07.2025 06:40

    Интересно про точки зрения (аналитические разрезы) которые применяете. Я так понимаю Java . Для своей области я применяю вот такие Сколько точек зрения у  Архитектора в ИТ? / Хабр


  1. ruomserg
    15.07.2025 06:40

    Нет, нет, и еще раз нет! Архитектура - это искусство выстраивания системы сейчас под требования, которые в моменте не предъявляются, не осознаются, и возможно даже не существуют. Проектирование системы под известные требования - это инженерия.

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

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

    Другой пример хорошей архитектуры - это человек. У вас достаточно точек гибкости в скелете, чтобы вы могли достать рукой до любого места тела (хотя и с разной степенью удобства). Если бы это было не так - можно было умереть загнав себе небольшую занозу и не имея возможности ее вытащить, и далее сепсис и проч... С другой стороны - в отличие от бесконечно гибкого осьминога - вы достаточно жестки чтобы жить на суше, переносить достаточно тяжелые предметы, манипулировать инструментами. Хотя при рождении, когда задачей является спать и есть мамкину грудь - важность этого функционала совершенно не очевидна.

    Сухой итог - архитектура это действительно компромисс. Компромисс между сложностью системы и ее возможностью адаптироваться к неизвестному будущему. Работа архитектора - не сводится к подбору компонентов под требования (хотя и это тоже надо делать). Настоящая работа архитектора (его насмотренность, опыт в отрасли и т.д.) - это сказать вам СЕЙЧАС как надо сделать, чтобы ПОТОМ каждый раз оказывалось: "...могла ли природа предполагать что нам понадобятся очки? А как удачно расположены наши уши!...". То есть, внешний мир изменяясь предъявляет новые требования к вашей системе - и внезапно оказывается что относительно небольшой кровью она может к ним адаптироваться. А у конкурента, который строил как лачуги в мумбае - нет!...


    1. Farongy
      15.07.2025 06:40

      Довольно забавно.

      Архитектура - это искусство выстраивания системы сейчас под требования, которые в моменте не предъявляются, не осознаются, и возможно даже не существуют. 

      Другой пример хорошей архитектуры - это человек.

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

      И как-бы проблемы со спиной коленями и много чем ещё не дадут соврать - получилось сильно не очень.


      1. ruomserg
        15.07.2025 06:40

        Я сказал "хорошей архитектуры", а не "идеальной". Оно выжило при нескольких глобальных похолоданиях, заселило все континенты кроме Антарктиды, живет во всех климатических поясах от Сахары до Чукотки. Понятно, что человека никто не проектировал - я это привожу как пример "случайно удачной" архитектуры которая прошла эволюционный отбор и оказалась достаточно хороша для широкого круга применений. А другие - более специализированные виды - нет... Вопрос об идеальной архитектуре я бы оставил открытой, ибо в какой-то момент вы упретесь в Парето-оптимальность и сможете только менять одни недостатки на другие...


        1. Farongy
          15.07.2025 06:40

          Архитектура - это искусство выстраивания системы сейчас под требования, которые в моменте не предъявляются, не осознаются, и возможно даже не существуют. 

          Понятно, что человека никто не проектировал - я это привожу как пример "случайно удачной" архитектуры которая прошла эволюционный отбор

          Я могу лишь в очередной раз предложить вернуть логику в программу обучения.


          1. ruomserg
            15.07.2025 06:40

            Логика в программе обучения - это прекрасно. Однако здравый смысл никто вам не отменит, ибо всякая достаточно сложная система либо неполна, либо противоречива. :-) Живите с этим. На всякий случай объясню еще раз. Человека никто не проектировал (если только вы не сторонник креационистской теории - но это уже к теологам, а не ко мне). Однако, практика показала что результат получился исключительно удачным. И мы можем указать на решения, которые делают его таковым.

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


    1. Rusya_2_0 Автор
      15.07.2025 06:40

      Нет, нет, и еще раз нет!

      Так а что конкретно нет?

      Архитектура - это искусство выстраивания системы сейчас под требования, которые в моменте не предъявляются, не осознаются, и возможно даже не существуют. Проектирование системы под известные требования - это инженерия.

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

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

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

      Другой пример хорошей архитектуры - это человек.

      Вот только человек это буквально пример эволюционирующей архитектуры.


  1. Lewigh
    15.07.2025 06:40

    Нет, нет, и еще раз нет! Архитектура - это искусство выстраивания системы сейчас под требования, которые в моменте не предъявляются, не осознаются, и возможно даже не существуют. Проектирование системы под известные требования - это инженерия.

    Когда архитектор проектирует новый ЖК он видимо делает это с расчетом что из него можно будет сделать в будущем аэродром? А если он просто проектирует ЖК в качестве ЖК, реализуя требования но вводя свое виденья по внешнего вида и конструктивных особенностей, он видимо и не архитектор чтоли?

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

    А молодой человек будет платить за тут избыточность которую заботливый архитектор внес в стоимость? А может быть вообще молодой человек будет жить с семьей не там а здесь только отдыхать а Вы ему построите дом для всей семьи, зачем?

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

    Хотелось бы спросить, а Вы сами то живете во дворце? А если нет то почему? Может быть в мире существуют такие понятия как стоимость, сроки, доступность и возможности? И лучше построить трущобы здесь и сейчас, чтобы люди могли бы жить хоть где-то, чем расселить всех по дворцам через 1000 лет?

    Другой пример хорошей архитектуры - это человек.

    Как раз пример отвратительной "архитектуры".


    1. ruomserg
      15.07.2025 06:40

      Вот архитектор вам на то и архитектор, чтобы объяснить ПОЧЕМУ вы должны некоторый ресурс потратить сейчас даже если не видите в этом необходимости. Потому что если этого не делать - тогда это просто инженерия: вот требования, вот нормы, бах-трах, подписывай акт хозяин - мы все сделали. Надо оно вам, не надо оно вам - это не инженера проблема, а заказчика.

      У архитектора - задача сложнее. Он должен понять чем заказчик живет и что у него болит. И да, предложить решение в рамках существующих ресурсных ограничений. Например, в СССР архитекторы с учетом ограничений предложили массовое панельное домостроение. А в США - suburbs с деревянными каркасниками. А если все совсем плохо - архитектор может вам вообще сказать что с такими ресурсами ничего строить не получится...

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


  1. Fardeadok
    15.07.2025 06:40

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


  1. Grikhan
    15.07.2025 06:40

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

    Очевидно, что при проектировании архитектуры необходимо придерживаться общих принципов проектирования - KISS и YAGNI. Но не менее важным является BDUF, при котором необходимо отделять основное от второстепенного с разделением на этапы (планированием) и проектировать не только с учетом контекста, но и с определенными заранее границами. Есть еще принцип DRY, по которому, если говорить об архитекторе, не нужно повторять одну и ту же логику в разных местах, а выносить в библиотеки и модули или, еще лучше, в отдельную функцию. Эти принципы куда более специфичны для архитектуры, чем более общие KISS и YAGNI.