Обновить
64K+

Проектирование и рефакторинг *

Реорганизация кода

45,67
Рейтинг
Сначала показывать
Порог рейтинга
Уровень сложности

Свежий взгляд на бронирование тайм‑слотов, или как я это сделал на Spring boot, используя пессимистические блокировки

Уровень сложностиСредний
Время на прочтение7 мин
Охват и читатели1.9K

Здравствуйте, Хабровчане! Меня зовут Дмитрий, я бэкенд разработчик Java. Недавно я наткнулся на задачу, которая сначала показалась мне копеечной, а потом сожрала неделю вечеров и заставила залезть глубоко в дебри конкурентных транзакций PostgreSQL.

Всё началось с обсуждения автоматизации одной частной клиники. Поначалу казалось, что сценарий простой: пациент хочет записаться на МРТ с контрастом. Обычный календарь записи (вроде Calendly или виджетов типа YClients) предлагает выбрать мастера и время. Но на деле всё оказалось не так просто...

Читать далее

Новости

Sequence в PlantUML — проще, понятнее, ярче… И стандартнее

Уровень сложностиПростой
Время на прочтение11 мин
Охват и читатели3.1K

Всем привет! Меня зовут Анатолий, я работаю ИТ-архитектором в Сбере. Занимаюсь развитием направления клиентской лояльности. Сразу же отмечу, что в этой статье не идёт речь о фундаментально правильных решениях. Скорее, наоборот, речь идёт о решениях компромиссных.

В целом, зрелость архитектурной культуры организации можно оценивать соответствием некому условному уровню. 

Если в вашей компании уже живёт полноценная система для архитектурных решений в виде Aris, Sparx Enterprise Architect или их аналог, и она умеет всё, что нужно: описывать бизнес-сценарии, собирать связанные с ними решения, показывать и согласовывать их с заказчиками, а потом аккуратно складывать в единый архитектурный репозиторий, то тогда, скорее всего, эта статья не для вас. Вы и так всё это проходили.

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

Читать далее

Как спроектировать API для мобильного приложения поверх монолитной системы

Уровень сложностиСредний
Время на прочтение10 мин
Охват и читатели2.6K

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

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

В этой статье разберу более устойчивый вариант: отдельный API‑слой между мобильным приложением и существующей системой. Без полной переработки монолита и без попытки сразу перейти на микросервисы.

Читать далее

Распределённые вычисления: гарантия завершения на исполнителях, которые вам ничего не должны

Уровень сложностиСредний
Время на прочтение52 мин
Охват и читатели8.6K

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

У вас, скорее всего, уже открыт десяток разнообразных вкладок: какая‑нибудь платформа с бесплатными недельными лимитами, вроде Kaggle; что‑нибудь с бесплатными возобновляемыми кредитами, на подобии Lightning AI; возможно, пара площадок со спотовыми машинами по цене чашки кофе, например Vast, но с оговоркой — никто не обещает, что машину не заберут, или у ее владельца не отвалится сеть.

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

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

Итак, приступаем...

Где взять гарантию, которая не существует?

Архитектура движка подбора билетов: три GDS, железная дорога и маршрут, который меняют в дороге

Уровень сложностиСредний
Время на прочтение10 мин
Охват и читатели8.8K

Референсная архитектура движка подбора билетов на redb: канонная модель, Scatter-Gather по трём GDS и ж/д, дерево-маршрут и saga-переоформление в дороге.

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

Три системы под самолёты (Amadeus, Sabre, Travelport) исторически несовместимы: разные XML-диалекты одного и того же понятия перелёта, выросшие из мейнфреймов 60–80-х, каждый со своими причудами и полями, которых нет у соседа. Плюс отдельная, никак не связанная с ними система бронирования под железную дорогу: свой формат, своя логика мест и классов, ничего общего по структуре с авиационными GDS. Запросить всё это параллельно, свести разноформатные ответы в одно и собрать валидный маршрут по стыковкам уже само по себе задача не для россыпи if и ручных мапперов.

А дальше человек в дороге меняет ...

Читать далее

9 ошибок при создании и внедрении автоматизаций в n8n

Уровень сложностиПростой
Время на прочтение8 мин
Охват и читатели5.8K

Автоматизация в n8n может собраться за полчаса, а через несколько месяцев превратиться в процесс, который страшно менять.

В статье — 9 ошибок проектирования и внедрения, из‑за которых такие сценарии становятся хрупкими, дорогими в поддержке и плохо передаются другим.

Читать далее

Код написали за нас. Как упростить ревью и сколько это стоит в рантайме

Уровень сложностиСредний
Время на прочтение20 мин
Охват и читатели9.2K

Последнее время я почти не пишу код руками — значительную часть реализации берут на себя AI-агенты. Но работы меньше не стало: теперь нужно задавать ограничения, проверять архитектуру и понимать результат, не перечитывая тысячи сгенерированных строк. Я попробовал сделать архитектурный граф общей моделью для человека, агента и генератора кода. Из одного графа получил сервисы на Go, Python, C++ и Rust, а затем сравнил их с прямыми реализациями того же HTTP → gRPC сценария. Главный вопрос эксперимента: какова runtime-плата за систему, которую проще понимать, изменять и наблюдать?

Читать далее

Пять дней ожидания: опыт длинных временных окон Kafka stream

Уровень сложностиСредний
Время на прочтение11 мин
Охват и читатели9.1K

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

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

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

Узнать больше

Вам не нужны микросервисы

Уровень сложностиПростой
Время на прочтение12 мин
Охват и читатели11K

Какое‑то время назад, проработав 3 года на позиции Java Middle+‑ разработчика на крупном монолитном легаси‑проекте (естественно, модульном), я столкнулся с тем, что не имел практики в создании приложений на микросервисной архитектуре. При этом я понимал, что работа с микросервисами — это работа с актуальным стеком технологий в мире Java. И если ты не работаешь с микросервисами, то ты вроде как не имеешь необходимой квалификации для большинства вакансий на рынке труда. По крайней мере, если судить по самим вакансиям.

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

Читать далее

Нефункциональные требования: 5 ошибок, которые всплывут в проде

Уровень сложностиСредний
Время на прочтение12 мин
Охват и читатели11K

Система прошла приёмку, но первая реальная нагрузка разогнала p99, исчерпала пул соединений и увеличила счёт за облако.

Разбираем пять ошибок в нефункциональных требованиях и способы превратить их в измеримые ограничения ещё до выхода в прод.

Читать далее

Устав и летопись кодинг-агентов

Уровень сложностиСредний
Время на прочтение6 мин
Охват и читатели7.4K

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

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

Читать далее

Отказ — это событие, а не статус: как мы перепроектировали модель данных исполнительного производства

Уровень сложностиСредний
Время на прочтение7 мин
Охват и читатели7.3K

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

Мы делаем платформу защиты авторских прав. Дальний конец процесса - взыскание денег по выигранному суду через приставов. Это конвейер: запросили исполнительный лист, получили, отправили, вручили, возбудили производство, дальше либо деньги, либо обжалование бездействия.

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

Читать далее

Как я сделал старый монолит на Laravel 8 — модульным, чтобы не плодить форки под каждого клиента

Уровень сложностиСредний
Время на прочтение8 мин
Охват и читатели8.2K

Изначально это был монолитный портал на Laravel 8, где user фронт и admin фронт лежали рядом с беком в одной папке. 

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

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

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

Поэтому, когда появилось время, я занялся этим проектом. Сразу поставил рамку, фреймворк не меняю, остаёмся на Laravel 8. Хотелось не переходить на другой язык, не заниматься переписыванием всего огромного бека, отделить всё в модули и переписывать уже поэтапно отдельные куски.

Читать далее

Ближайшие события

Правила программирования Роба Пайка

Уровень сложностиПростой
Время на прочтение10 мин
Охват и читатели22K

В этой рубрике мы уже рассказывали про Кена Томпсона и Денниса Ритчи, соавторов Unix, UTF-8 и операционной системы Plan 9. Они практически всю жизнь работали вместе в Bell Labs (AT&T, потом Lucent) как коллеги и единомышленники. Так вот, третьим членом их коллектива был Роб Пайк.

Кроме соавторства Unix и нескольких учебников по программированию, он известен как создатель языка программирования Go. Этот язык родился из философии простоты в программировании, которую Пайк пропагандирует всю жизнь.

Читать далее

«У вас в резюме указаны навыки ИИ. Что вы имели в виду?» Что отвечать, кроме количества потраченных токенов

Уровень сложностиПростой
Время на прочтение53 мин
Охват и читатели11K

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

Один говорил, что весь навык сводится к умению нормально сформулировать запрос, всё остальное сделает модель. Другой доказывал, что настоящее умение это как раз не пускать ИИ туда, где он навредит, и что главный навык это дисциплина отказа. Третий считал, что тема надутая, а через год всё устаканится само и учиться нечему. Четвёртый прислал скриншот своего CLAUDE.md на двести строк и сказал, что вот она, настоящая работа.

Меня зацепило, что мы все вроде бы делаем одно и то же каждый день, а описываем это несовместимыми словами. Ни у кого, включая меня, не оказалось внятного ответа на простой вопрос: если разработчик говорит «я умею работать с ИИ», что конкретно он умеет?

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

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

Читать далее

Экономическая выгода рефакторинга в эпоху AI-агентов

Время на прочтение9 мин
Охват и читатели7K

Осваивая разработку с помощью AI-агентов, я написал веб-приложение для собственной ежедневной работы. Проект получился довольно сложным: с динамическим обновлением интерфейса и поиском, модальными окнами, автосохранением, интеграциями с внешними системами, модулями машинного обучения, текстовым анализом, фоновыми задачами и автоматическим деплоем. Объём кода составил около 150 000 строк, из которых примерно 120 000 написаны на Rust, а остальные - на TypeScript и Terraform.

Весь этот код сгенерировали агенты - в основном Claude Code и частично Cursor. За редкими исключениями я почти не открывал и не читал исходные файлы.

В процессе разработки я начал замечать странности. Когда в терминале мелькнула правка 4000-й строки в одном файле, я решил посмотреть на код ближе. Выяснилось, что слой доступа к данным разросся до 6000 строк. С каждой новой функцией он продолжал расти. В коде каждого запроса, чтения или записи повторялись настройка HTTP-запроса, кодирование и декодирование JSON. В итоге весь слой доступа к данным оказался в одном файле на 17 155 строк Rust.

Читать далее

Архитектура TMS на .NET: кластер, потоки координат и объектное хранилище

Уровень сложностиСложный
Время на прочтение12 мин
Охват и читатели11K

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

Коротко о предмете. Заказы приезжают из SAP, под них подбираются водитель и машина с учётом требований к транспорту и к точкам. Рейс идёт по точкам с временными окнами, на точках чек-листы, при выдаче и возврате машины составляются акты с фиксацией повреждений. Сверху — поток GPS-координат, отслеживание рейсов и мест, мобильное приложение водителя и публичный контур, где клиент видит свою доставку.

Пятнадцать модулей, три ноды за балансировщиком, RabbitMQ и Kafka по три ноды, PostgreSQL, Redis из шести.

Читать далее

Я хотела дать AI память. Пришлось организовать работу

Уровень сложностиСредний
Время на прочтение26 мин
Охват и читатели7.2K

У меня есть три правила работы с контекстом.

Первое правило работы с контекстом - выносить его из чата.

Второе правило работы с контекстом - прежде чем выносить, нужно сортировать.

Третье правило работы с контекстом - не в контексте дело.

Читать далее

Переезд с ESB на свой стек: что реально экономит бизнес

Уровень сложностиСредний
Время на прочтение41 мин
Охват и читатели11K

Разбираем систему управления транспортом — TMS. Заказы приезжают из SAP, под них подбираются водитель и машина с учётом требований, рейс идёт по точкам с временными окнами, на точках чек-листы, при выдаче и возврате машины — акты с фиксацией повреждений. Сверху поток GPS в партиционированные таблицы, отслеживание рейсов и мест, мобильное приложение водителя и публичный контур, где клиент видит свою доставку. Пятнадцать модулей, три ноды за балансировщиком, RabbitMQ и Kafka по три ноды, Redis, PostgreSQL, отдельный сервер идентичности.

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

Команда была ....

Читать далее

Сколько стоит интеграционный слой на WSO2 MI и EF Core: разбор реальной системы по строкам

Уровень сложностиСредний
Время на прочтение23 мин
Охват и читатели11K

Разбираем систему управления транспортом — TMS. Не игрушечную и не с конференции: заказы приезжают из SAP, под них подбираются водитель и машина с учётом требований к транспорту и к точкам, рейс идёт по точкам с временными окнами, на точках — чек-листы, при выдаче и возврате машины составляются акты с фиксацией повреждений. Сверху — поток GPS-координат в партиционированные таблицы, отслеживание рейсов, мест и контрагентов, определение присутствия по WiFi. Плюс мобильное приложение водителя и публичный контур, где клиент видит, где его доставка.

Пятнадцать модулей, три ноды за балансировщиком, RabbitMQ и Kafka по три ноды, Redis, PostgreSQL, отдельный сервер идентичности.

Зачем её вообще стали писать. TMS покупали как услугу у внешних поставщиков, и риски выросли.

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

Систему забрали себе.

И вот главное ...

Читать далее
1
23 ...