Когда программист впервые слышит слово «архитектура», он обычно представляет что-то скучное: диаграммы, стрелочки, коробочки, совещания на три часа и человека, который запрещает писать код.

А потом проходит несколько лет.

И внезапно оказывается, что проект, который «быстро накидали», начинает разваливаться от любого изменения.

Добавили одну кнопку — сломался импорт. Поменяли отчёт — умерла авторизация. Обновили библиотеку — перестала открываться половина форм.

И начинается археология.

Почему так происходит?

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

Архитектура — это не про красоту

Есть популярное заблуждение:

«Архитектура нужна большим корпорациям. Маленькому проекту она не нужна».

Это неправда.

Архитектура — это не красивые картинки для начальства. Это ответ на очень практичный вопрос:

«Сколько боли будет при следующем изменении системы?»

Если любое изменение страшно — архитектура плохая.

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

Самая опасная вещь в проекте — успешный старт

Это ловушка, в которую попадали почти все.

Сначала всё прекрасно: один разработчик, одна база, один проект, «сейчас быстро сделаем MVP».

Потом появляется второй программист, третий модуль, интеграции, отчёты, уведомления, API, права доступа, фоновые задачи.

И внезапно система начинает напоминать подвал, где за 10 лет никто не разбирал провода.

Я видел проекты, где архитектура буквально убивала систему

Один из самых жёстких случаев был в сметной программе.

Файл сметы весил около 2 МБ. После загрузки в память он разворачивался примерно в 600 МБ. Каждое изменение документа увеличивало потребление памяти ещё процентов на 20.

Самое прекрасное — после закрытия сметы память не освобождалась.

Потому что были циклические зависимости, и объекты продолжали держать ссылки друг на друга.

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

И проблема была не в языке. Не в Windows. Не в железе.

Проблема была в архитектуре.

«Но у нас же DLL!»

Это тоже классика.

Формально проект может быть разбит на модули.

На практике:

— DLL ссылается на форму
— форма лезет в базу
— SQL написан прямо в UI
— бизнес-логика вызывает элементы интерфейса
— модуль A знает про B, C, D и половину алфавита

Особенно весело это выглядит в старом enterprise.

В одной медицинской системе я видел SQL прямо внутри форм.

2023 год.

Не ORM. Не DAL. Не репозитории.

Прямой SQLConn из UI.

При этом проект был «разделён на DLL». Но DLL были перекрёстно связаны настолько, что любое изменение тянуло за собой каскад зависимостей.

Выглядело модульно. По факту — тот же монолит, только нарезанный кусками.

Монолит — не проблема

Вот здесь начинается священная война интернета.

Многие почему-то думают:

монолит = плохо
микросервисы = хорошо

На практике всё сложнее.

Плохой монолит — это когда нет границ ответственности.

Хороший модульный монолит может жить годами и прекрасно масштабироваться. Особенно если:

— есть чёткое разделение слоёв
— бизнес-логика отделена от UI
— зависимости контролируются
— модули общаются через интерфейсы
— нет циклических ссылок

Для большинства проектов модульный монолит вообще является лучшим стартом.

Потому что микросервисы — это не «магическая современная архитектура». Это цена. Иногда оправданная. Иногда — нет.

Микросервисы не решают проблему плохого кода

Они просто распределяют её по сети.

Вместо одного спагетти-монолита получается распределённое спагетти: с таймаутами, очередями, контейнерами, сетевыми ошибками и ночными поисками причины, почему сервис авторизации отвечает 502 только по вторникам.

Хорошая архитектура — это прежде всего понятные связи

Главный признак здоровой системы — предсказуемость.

Ты понимаешь:

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

И желательно, чтобы цепочка выглядела так:

A → B

а не:

A → B → C → E → A → форма → SQL → XML → внезапно SMTP

Потому что именно так рождается настоящий enterprise-хоррор.

Самая дорогая ошибка — «потом отрефакторим»

Не отрефакторите.

Почти никогда.

Потому что потом появляются сроки, дедлайны, новые фичи, прод, поддержка и «срочно надо клиенту».

И временный костыль становится частью системы. Навсегда.

Тут очень подходит старая фраза из советского мультфильма:

«Лучше день потерять — потом за час долететь».

В архитектуре это работает буквально.

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

Иногда правильная архитектура даёт чудовищный прирост производительности

Был у меня случай с Oracle.

Тяжёлая процедура: десятки миллионов строк, 4–5 JOIN, составные JOIN, всё через старый SQLConn.

Работало примерно 25 минут.

Сначала я прикрутил ORM (Entity Framework), разбил логику на подзапросы и начал стягивать данные асинхронно.

Память выросла процентов на 20–25. Зато время выполнения упало до 12 секунд.

Потом задача была разбита по потокам.

Итог — меньше секунды.

И это важный момент: архитектура — это не только «красиво». Очень часто это ещё и производительность.

Есть старая инженерная мудрость: не катить прод в пятницу

Потому что вселенная воспринимает это как вызов.

Однажды начальство очень хотело выкатить обновление именно в пятницу утром.

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

Ответ был классический:

«Да всё нормально будет, выкатывай».

Ну хорошо.

Выкатил и уехал.

18 вечера. Лес. До ближайшей цивилизации километров тридцать.

И тут звонок:

— «У нас всё не работает. Срочно чини».

Интернета почти нет.

В итоге я сидел на сосне метрах в пяти над землёй и правил код прямо на сервере с телефона, потому что только там ловила связь.

С тех пор к пятничным релизам я отношусь философски.

Главная проблема легаси — не старость

А отсутствие границ.

Старый код может быть нормальным.

Я видел проекты начала 2000-х, которые до сих пор поддерживать легче, чем некоторые современные «ультрамодные» системы.

Потому что там были понятные модули, нормальная декомпозиция, минимум магии и прозрачные зависимости.

И наоборот: можно за полгода превратить новый проект в технический Чернобыль.

Итог

Архитектура — это не про элитарность.

Не про «настоящих инженеров».

И не про диаграммы ради диаграмм.

Это способ сделать так, чтобы система пережила:

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

Потому что главный враг проекта — не язык. Не фреймворк. Не база данных.

А хаос связей внутри системы.

И чем раньше программист это понимает — тем меньше шансов однажды разгребать shop_final_new2_REAL_fix_v7.cs в пятницу ночью.

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


  1. kadmy
    15.05.2026 15:26

    Вообще всё гораздо проще. Если кодер не архитектор, то он джун, хотя может притворяться кем угодно.


    1. Sun-ami
      15.05.2026 15:26

      Это если есть внятные ТТ и ТЗ. А без них архитектура ХЗ как и всё остальное. Надо быть опытней менеджеров, чтобы предсказать, во что может превратиться система в итоге. Мидлам это обычно не под силу.


      1. kadmy
        15.05.2026 15:26

        Вот, допустим, пишет такой человек для себя. Пет-проект. Есть у него в одиночку шанс написать приличное количество кода, чтобы это был не говнокод? Нет. Так о чем речь?


        1. Sun-ami
          15.05.2026 15:26

          Речь о том, что требования к архитектуре разные в зависимости от размеров проекта. То, что начинается как проект на месяц причём делающийся одним человеком в сумасшедшей спешке, в итоге нередко вырастает в проект на 10 лет и 50 человек, которые участвуют в него в разное время. И за эти 10 лет успевает несколько раз радикально смениться аппаратная база и фреймворк. С пет-проектами ситуация иная - спешки нет, и автор изначально примерно представляет перспективы. А так приходится глубоко рефакторить, в том числе и архитектуру. Но полностью рефакторить проект удаётся очень редко, так что в итоге легаси хватает.


  1. Lewigh
    15.05.2026 15:26

    Ну предположим архитектура важна. А дальше то что? На этом вся статья? Ну я не знаю, ну написали бы как делать хорошо и не делать плохо. Можно с тем же успехом написать статьи что хорошая аналитика важна и хорошее тестирование, только положение дел это не особо изменит.


    1. singlevolk Автор
      15.05.2026 15:26

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


      1. Emelian
        15.05.2026 15:26

        если интересно предложите тему или какой-нибудь случай…вполне возможно он у меня на практике был…все таки более 26 лет в разработке

        Я могу рассказать о своём случае, но не уверен, что он вписывается в ваши интересы, поскольку, предпочитаю вею-программированию – десктопное.

        У меня опубликована, здесь, первая версия обучающей, иностранным языкам, программы «L’école». Там, я слегка накосячил:

        Структура первой версии обучающей программы «L'école»
        Структура первой версии обучающей программы «L'école»

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

        На первое место, в этом случае, выходит роль модулей либо автономных классов в С++. А также организация их в «правильную» иерархию. Затем выбор концепции программы и ее программной логики. Потом, разработка алгоритмов и их техническая реализация. Ну и плюс расширение возможностей программы по сравнению с первой версией.

        Оказывается, что даже в этом простейшем случае, с архитектурой не все ясно. Ну, допустим, стал я «архитектором» и дали мне команду из нескольких программистов (нет, несколько – это мало, пусть их будет в два раза больше!). Какие указания я им должен раздать, чтобы «процесс пошёл»?

        Понятно, что задача должна быть максимально «распараллелена», Но, для модульного программирования на С++ нет общепринятой методологии. У меня была здесь статья на эту тему, где я использовал динамические и статические плагины для параллельной разработки, однако, народ её воспринял в штыки. Наверное, если я напишу новую статью об архитектуре второй версии своей программы, реакция будет такой же. Ибо, как я понял, народ привык воспринимать модули на С++, примерно, как пакеты в Питоне. Но, ведь, вторую версию мне писать надо? – Надо! Оригинальность проявлять надо? – Надо, не надо, но вынужден, ибо другого пути построения новой версии программы – не вижу. Кстати, при создании её первого варианта, я себе чуть мозги не сломал, пока не добился её более-менее рабочего состояния.

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


        1. singlevolk Автор
          15.05.2026 15:26

          Не расстраивайтесь...на С++ можно даже писать микросервисы...я 10 лет писал на С++ :) и ооп там вполне рулит.
          На самом деле я бы на вашем месте сейчас не пытался сразу «изобрести идеальную архитектуру». Это ловушка, в которую очень легко попасть при написании второй версии :)

          Судя по диаграмме, главная проблема у вас даже не в количестве файлов, а в плотности связей между ними. И это абсолютно типичная история

          Поэтому я бы начал не с «идеальной иерархии», а с разделения системы на логические блоки с понятными границами.

          Например:

          • UI

          • обучение/уроки

          • тестирование

          • мультимедиа

          • работа с БД

          • настройки

          • общие сервисы/утилиты

          И даже если внутри блока пока останется своё маленькое «спагетти» — это уже будет гораздо лучше, чем одна большая общая кастрюля :)

          Потому что хорошая архитектура — это не отсутствие хаоса. Это ограничение радиуса его распространения.

          А дальше уже можно постепенно:

          • уменьшать связанность

          • вводить интерфейсы

          • убирать прямые зависимости

          • выносить общую логику

          • и приводить систему в порядок без тотального переписывания.

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


          1. Emelian
            15.05.2026 15:26

            Не расстраивайтесь…на С++ можно даже писать микросервисы…

            Вопрос только, нужно ли? Модули, в программе для ПК – я понимаю, сервисы – нет. Локальные сервисы в Windows – это те же (системные) службы, т.е., просто фоновые процессы. Или вы имеете в виду многопоточное программирование?

            я 10 лет писал на С++ :) и ооп там вполне рулит.

            Я в этом ни разу не сомневался, особенно, используя WTL.

            Судя по диаграмме, главная проблема у вас даже не в количестве файлов, а в плотности связей между ними. И это абсолютно типичная история

            Да, файлов там не много, проблема, действительно, в сильных связях. Я это объясняю наличием связей «многие ко многим». А, как мы знаем, из теории БД, их можно заменить связями: «многие к одному» и «один ко многим». Может быть, даже, удастся свести их, только, ко второй части данных отношений.

            Поэтому я бы начал не с «идеальной иерархии», а с разделения системы на логические блоки с понятными границами. Например:

            В терминах модулей, это будут:

            • Главный модуль (точка входа)

            • Класс приложения

            • Главное окно приложения

            • Обработчики главного окна приложения

            • Модули автономных классов, используемые в обработчиках

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

            Потому что хорошая архитектура – это не отсутствие хаоса. Это ограничение радиуса его распространения.

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

            Кстати, вот скриншот первой версии программы, о которой мы говорим:

            Простые озвученные фразы на английском языке, с переводами
            Простые озвученные фразы на английском языке, с переводами


            1. singlevolk Автор
              15.05.2026 15:26

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


          1. kadmy
            15.05.2026 15:26

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


            1. Emelian
              15.05.2026 15:26

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

              Очень спорное утверждение!

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

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

              Классы вполне могут быть «большими», особенно, если это классы WTL. Сделаны они, на редкость хорошо. И, хотя, их (открытый) код не превышает полутора мегабайт, менять там, что-либо, у меня, ни разу не возникло необходимости. Как по мне, WTL самодостаточен, и не нуждается, особо, в расширении либо модификации. Оставим этот путь для Qt.

              Собственные классы, тоже могут быть не маленькими. Главное, чтобы они были максимально локализованы. Возникла проблема? Ага! Это в модуле «Х», начинаем его «шерстить». Смотрим логи, запускаем отладку и т.п… Находим проблему и исправляем ее. Более того, если нужно данный модуль отключить, то, просто заменяем его полную версию – формальной. Вызовы из него, в основной программе, останутся, но они ничего делать не будут.

              Соответственно, наоборот. Архитектор делает прототип программы с формальными (пустыми) реализациями базовых функций классов. Задача программистов – исполнителей – заменить пустые реализации публичных функций в классах – их полными аналогами. Затем мы просто делаем подмену формальных модулей – реальными и, вуаля, сразу получаем дополнительный функционал в приложении. При этом, программисты могут, на свое усмотрение добавлять в «свои» модифицируемые классы приватные функции и приватные данные. Главное, они не должны менять интерфейс публичных функций и, может быть, публичных данных, определенный архитектором.

              Также, можно менять одну вервию модуля на другую (путем простой подмены его файлов)

              Таким образом, модули (автономные классы) в C++ / WTL – должны, как легко подключаться к приложению, так и легко отключаться, без модификации кода вызова их публичных функция в обработчиках приложения. Что также позволит, без проблем, менять одну версию модуля на другую.

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


  1. Zx2001
    15.05.2026 15:26

    На хабре без ллм вообще ни кто не пишет больше? Печалька. Хотя бы причесывали текст после.


  1. kedzoo
    15.05.2026 15:26

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