Обновить
128K+

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

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

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

От хаоса к порядку: как управлять техдолгом

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

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

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

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

Читать далее

Новости

Дубль один, дубль два: как я делала одну фичу дважды

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

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

Оба продукта — CDP (Customer Data Platform) для маркетинга. По сути это база данных, которая собирает информацию о клиенте отовсюду и нарезает её в сегменты, — а сверху на эту базу наслаиваются рассылки, бонусы и акции, ласково выманивающие клиента с дивана. Задача-дубль — конструктор сценариев: визуальный редактор, где кампания собирается цепочкой блоков. Классика жанра — сценарий на день рождения:

Читать про оба дубля

Назад в 2005-й. API-first как третья пилюля от деградации проекта под LLM

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

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

Под катом — как этот шов гниёт под LLM и как его чинит contract-first: генерация серверных интерфейсов и клиента из одного OpenAPI-файла, политика ломающих изменений, правило «не симулируй — расширяй контракт». Попутно — зачем возвращаться к идее, которую мы выбросили вместе с WSDL, и какая из моих проверок после всего этого молча перестала работать. Третья часть цикла, читается самостоятельно.

Читать далее

Свободные функции вместо методов, но с полиморфизмом. Что это даёт на самом деле?

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

Речь о процедурно‑параметрическом программировании, о котором почти никто не пишет. Я реализовал одну и ту же задачу в ООП и в этой парадигме и сравнил их численно. Одна из метрик разошлась в 6 раз.

Что же это такое?

С++: Пиши, сокращай, оптимизируй

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

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

Читать далее

Надёжная асинхронная коммуникация: повторы, дубликаты и dead letter queues

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

Представим обычную обработку заказа. Сервис заказов публикует событие order.created. Сервис склада получает его и резервирует товар в PostgreSQL. После успешной транзакции обработчик должен отправить RabbitMQ подтверждение (Ack), чтобы broker удалил сообщение из queue.

Но процесс может остановиться после записи в PostgreSQL и до отправки Ack. RabbitMQ не знает, успел ли сервис зарезервировать товар. Broker видит только неподтверждённое сообщение, поэтому доставляет его ещё раз. С точки зрения доставки это правильное поведение. С точки зрения бизнеса один заказ теперь может зарезервировать товар дважды.

Другой сбой возникает раньше: PostgreSQL временно недоступен, и обработчик не может начать работу. Если сразу вернуть сообщение в queue через отрицательное подтверждение Nack(requeue=true), RabbitMQ почти немедленно доставит его снова. Пока база не восстановилась, все попытки будут бесполезными. Нужны задержка и ограничение числа повторов. При этом отложенное сообщение может пропустить вперёд более новые события, поэтому отдельно придётся решить вопрос порядка.

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

В статье разберём эти моменты по всему пути сообщения. Затем построим практическую схему для RabbitMQ и Go: добавим ограниченные повторы через retry queues, время жизни сообщения (TTL) и dead letter exchange, сделаем обработчик идемпотентным и определим, куда отправлять сообщения, которые не удалось обработать автоматически. В конце сравним этот подход с Kafka, NATS JetStream и Amazon SQS.

Читать далее

Циклические реактивные зависимости

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

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

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

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

Вырваться из бесконечного цикла

AI-centric архитектура Flutter-приложения (и не только) для небольших стартапов

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

Мысли о масштабируемой архитектуре приложений через кодовую структуру и философии «developer as a user»; подходит для indie-разработчиков и стартапов на ранних стадиях.

Читать далее

Greenfield и Brownfield: разработка новых и существующих систем в эпоху AI

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

Новый сервис в пустом репозитории легко назвать greenfield. А если он должен заменить часть работающей системы, перенести данные за десять лет, сохранить старый API и пройти аудит? «Чистое поле» быстро заканчивается - обычно где-то между первой интеграцией и миграцией данных.

Greenfield и brownfield описывают не возраст и не качество кода, а количество уже существующих ограничений. В greenfield главная задача - проверить гипотезы о будущем продукте. В brownfield - разобраться в накопленных зависимостях и ничего важного не сломать.

С распространением AI-ассистентов и coding agents это различие стало ещё заметнее. Они впечатляюще быстро создают приложение с нуля. Но сколько профессиональной разработки действительно начинается с пустого репозитория? Гораздо чаще нужно сначала понять существующую систему, а затем безопасно изменить её поведение.

Читать далее

Пятая кнопка за вечер. Архитектура фронтенда под контекст LLM

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

К концу второго месяца vibe coding на фронте моего пет-проекта жили пять компонентов кнопки, четыре спиннера, компонент страницы на 700 строк и шапка, которая показывала один баланс, пока модалка рядом показывала другой. LLM-агент писал всё это уверенно, быстро и с хорошим стилем кода. Фронтенд под LLM деградирует даже быстрее бэкенда — и тому есть причины: от качества обучающей выборки, где вперемешку лежат три поколения React, до самой природы JSX, где разметка, логика и состояние легально живут в одном файле.

Под катом — что в итоге сработало: Feature-Sliced Design, урезанный до трёх слоёв, как карта для агента; dependency-cruiser в роли архитектурного контракта, который нельзя нарушить; кодогенерация API-клиента из OpenAPI вместо доменной модели; за что я простил Tailwind; и честно — про самое слабое место конвейера: агент, который верстает вслепую. Это продолжение статьи про бэкенд, но читается и само по себе.

Читать далее

Почему фронтенд съедает больше времени, чем бэкенд

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

Статья про то, как построить приложение с AI-ассистентом и не застрять на самом неприятном месте, когда бэк готов, а интерфейс внезапно съедает недели.

Почему современный фронтенд сложнее, чем кажется снаружи. Особенно если вы идёте через spec-driven development, пишете требования вместо кода и ждёте, что Claude, Cursor или Kiro быстро соберут работающий продукт.

👀 Внутри: перекос фронта и бэка по объёму кода, состояние кнопок и форм, дизайн-системы, локализация, accessibility, тысячи npm-зависимостей, скучные интерфейсы от LLM, Playwright MCP, Figma MCP, визуальные тесты и планирование проекта с нормальным запасом на UI-грабли.

Заходите, читайте и делитесь своим опытом AI-разработки ❤️

Читать далее

Лучшая архитектура KMP-приложений и когда её не использовать. Часть 2

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

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

Это вторая, практическая, часть из двух. Здесь про то, как организованы слои, какие контракты уходят в Swift, как готовить SKIE, как устроены обработка ошибок и DI, что с модульностью, скоростью сборки и тестами.

Читать далее

Новая версия языка разметки текстов Markvan

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

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

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

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

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

LLM говнокодит не хуже людей. Только быстрее

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

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

Под катом — что я понял и что в итоге сработало: почему LLM деградирует на плохой архитектуре точно так же, как команда людей; почему SOLID, DDD и чистая архитектура не устарели, а стали важнее; и как превратить архитектурные договорённости из «пожеланий в CLAUDE.md» в контракт, который машина не может нарушить. С конкретикой: два конфига deptrac для Symfony-бэкенда и пайплайн разработки с субагентом-ревьювером.

Читать далее

Миграция с Flutter Web на Jaspr: наш опыт

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

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

Недавно мы попробовали мигрировать наше приложение с Flutter Web на Jaspr – под катом расскажем о том, почему мы это сделали, с какими трудностями столкнулись и какие выводы сделали.

Да кто такой этот Jaspr?!

Лучшая архитектура KMP-приложений и когда её не использовать. Часть 1

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

В архитектуре KMP+CMP-приложений главный вопрос не в том, сколько кода можно пошарить. Он в том, где нужно остановиться.

Я покажу два рабочих подхода. Первый — архитектура для большого мобильного продукта: общий Kotlin-слой для бизнес-логики и нативный UI на каждой платформе. Второй — стартаповый путь, где Compose Multiplatform помогает быстро запустить мобильные продукты, web- и desktop-приложения. И даже backend на общих моделях данных.

Поговорим о том, когда нужно и не нужно применять «лучшую» архитектуру.

Читать далее

От REST к MCP: как LLM меняют принципы проектирования API и архитектуры систем. Часть вторая

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

Привет, Хабр! На связи Дмитрий Бондарев, я backend-разработчик Авито — занимаюсь проектами на стыке разработки и машинного обучения. В первой части этого материала мы обратились к истокам API и существующим ограничениям интерфейса в работе с агентами.

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

Читать далее

Технический долг — это не только legacy: как мы уменьшаем разброс решений между Go-сервисами

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

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

Для нас в QIC digital hub это особенно заметно на фоне миграции на новый Go-бэкенд. Исторически платформа развивалась на разнородном стеке: разные части системы были написаны на разных технологиях. Сейчас мы постепенно переезжаем на Go. Часть сервисов уже в проде, часть ещё на пути. Именно в такой момент легко создать новый слой техдолга поверх старого: переписать поведение на новом языке, но оставить команды один на один с десятками одинаковых инфраструктурных задач, которые каждая решает по-своему.

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

- go-kit — общая библиотека с переиспользуемыми инженерными решениями;

- go-service-template — шаблон, который делает эти решения стандартным способом запуска нового сервиса;

- shared-renovate-config — общий Renovate-конфиг с единой политикой обновления зависимостей для всех репозиториев.

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

Читать далее

От REST к MCP: как LLM меняют принципы проектирования API и архитектуры систем. Часть первая

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

Привет, Хабр! Говорит AvitoTech. Меня зовут Дмитрий Бондарев, я backend-разработчик, в Авито занимаюсь проектами на стыке разработки и машинного обучения. 

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

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

Читать далее

ArchiMate 4.0: собираем первую модель с нуля за 6 шагов

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

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

В этой статье разберём, как на ArchiMate 4.0 собрать первую рабочую модель предприятия с нуля — на примере интернет‑магазина, с понятной логикой доменов, связей и проверок, которые помогают не превратить диаграмму в клубок стрелок.

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