Rain Lag

90‑минутный рефакторинг: как короткие сессии по уборке кода со временем превращают хаотичные проекты в поддерживаемые

Как короткие, сфокусированные сессии рефакторинга могут постепенно превратить запутанный легаси‑код в поддерживаемую, качественную систему — без срывов сроков поставки.

90‑минутный рефакторинг: как короткие сессии по уборке кода со временем превращают хаотичные проекты в поддерживаемые

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

Вам нужно 90 минут.

Не один раз — а регулярно.

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

В этом посте — как устроены 90‑минутные сессии рефакторинга, почему они так эффективны и какие практические приёмы можно безопасно применять даже в хрупких системах.


Почему работает рефакторинг с жёстким таймбоксом

Рефакторинг часто откладывают, потому что он кажется большим и рискованным. Менеджеры боятся: «Если дать разработчикам рефакторить, мы никогда ничего не выпустим». Разработчики боятся: «Если я это трону, всё сломается».

Таймбоксинг — например, блоки по 90 минут — снимает оба этих страха.

1. Он не даёт заботе о качестве убить сроки поставки

Таймбокс в 90 минут достаточно длинный, чтобы сделать что‑то ощутимое, и достаточно короткий, чтобы не развалить спринт.

Вы можете:

  • Планировать одну‑две 90‑минутные сессии в неделю
  • Привязывать их к текущей работе (например, к фиче или багфиксу)
  • Держать их видимыми на доске (отдельные задачи типа «Refactor»)

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

  • Коммитите небольшой, безопасный шаг вперёд
  • Оставляете TODO или заводите тикет на продолжение

Через недели и месяцы эти сессии складываются в реальные структурные улучшения — без просьб к стейкхолдерам профинансировать огромный и рискованный проект «глобального рефакторинга».

2. Он снижает психологический порог входа

«Сделать платёжную систему не такой ужасной» — звучит как неподъёмная задача.

«Потратить 90 минут, чтобы сделать только этот метод менее ужасным» — уже по силам.

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


Инкрементальный рефакторинг: как безопасно эволюционировать легаси‑код

Выбросить всё и переписать заново — соблазнительно и опасно. Инкрементальный рефакторинг — скучный и мощный.

Инкрементальный рефакторинг — это:

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

Вместо:

«Через 3 месяца полностью заменим этот модуль»

Вы делаете:

«Каждую неделю делаем этот модуль чуть менее болезненным — и при этом не прекращаем релизить»

Признаки хороших инкрементальных изменений

За 90‑минутную сессию «хороший» рефакторинг — это:

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

Примеры безопасных инкрементальных шагов:

  • Переименовать запутанный метод и обновить все места вызова
  • Разбить 200‑строчный метод на несколько небольших вспомогательных с понятными именами
  • Заменить «магическое» число или строку на именованную константу или конфигурационный параметр
  • Ввести небольшой, специализированный класс, который инкапсулирует одну грязную ответственность

Со временем эти маленькие шаги перекраивают даже самый уродливый легаси‑код во что‑то цельное и понятное.


Тестирование: ваша страховка при рефакторинге

Рефакторинг без тестов — как хирургия без диагностики.

Сильные практики тестирования превращают рефакторинг из рулетки в контролируемый, повторяемый процесс.

Что значит «сильное тестирование» в этом контексте

Не нужен 100% coverage, но вам нужно следующее:

  • Быстрые автоматические тесты — чтобы их можно было гонять снова и снова в течение 90‑минутной сессии.
  • Покрытие критичного поведения — потоки, где сбой особенно дорог: платежи, аутентификация, целостность данных.
  • Индикаторы доверия — если тесты зелёные, вы с разумной уверенностью считаете, что не сломали ядро поведения.

Если вы стартуете с плохими тестами

В по‑настоящему запущенных системах рефакторинг часто начинается с… написания тестов.

Хороший шаблон:

  1. Определить конкретное поведение или баг.
  2. Написать тест, который фиксирует текущее (пусть даже ужасное) поведение.
  3. Запустить тест и посмотреть, проходит он или падает.
  4. Рефакторить маленькими шагами, постоянно прогоняя тестовый набор.

Первую 90‑минутную сессию вы вполне можете потратить только на characterization tests — тесты, которые документируют, что код делает сегодня, до очистки.

Потом эти тесты будут страховать вас, пока вы переформатируете код в следующих сессиях.


Практические паттерны рефакторинга для грязного кода

Ниже — простые приёмы, которые отлично подходят для 90‑минутных блоков рефакторинга.

1. Переименование ради ясности

Цель: чтобы код читался как объяснение предметной области.

Примеры:

  • doStuff()calculateOrderTotal()
  • flagisEligibleForDiscount
  • dataMapcustomerIdToSubscription

Переименование — низкорисковое, но очень полезное для понимания изменение. Современные IDE делают его почти механической и безопасной операцией.

2. Extract Method (выделение метода)

Цель: разбить длинные функции на именованные, переиспользуемые блоки.

Пример «до»:

void processOrder(Order order) { // validate // apply discounts // calculate totals // send confirmation email }

Пример «после» (за несколько сессий):

void processOrder(Order order) { validate(order); applyDiscounts(order); calculateTotals(order); sendConfirmation(order); }

Каждый выделенный метод получает собственные тесты — либо покрывается уже существующими.

3. Extract Class (выделение класса)

Цель: вынести связанный набор поведения и данных в отдельный тип.

Если класс или модуль «делает всё на свете», ищите швы:

  • Платёжная логика
  • Email‑уведомления
  • Расчёт цен

Пример: вынести логику ценообразования из OrderService в PriceCalculator. В одной 90‑минутной сессии можно перенести одну‑две функции, остальное — постепенно.

4. Введение параметра или конфигурации

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

Примеры:

  • Заменить разбросанные по коду if (country == "US") на стратегию или запрос в конфигурацию.
  • Использовать MAX_RETRY_ATTEMPTS вместо голой 3 в нескольких местах.

Часто это можно делать постепенно: вводите константу и по шагам переводите на неё вызывающие участки.

5. Обёртка вокруг внешних зависимостей

Цель: создать стабильный шов вокруг внешних API и библиотек.

Оборачиваем прямое использование вроде:

axios.post("https://service/endpoint", data)

в локальную абстракцию:

paymentClient.chargeCustomer(customerId, amount)

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


Рефакторинг как путь к «качеству на скорости»

Современные команды постоянно под давлением: выпускать быстрее, адаптироваться быстрее, восстанавливаться быстрее.

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

Как 90‑минутные рефакторинги ускоряют команду

Со временем команды, которые сознательно вкладываются в качество кода и привычку регулярно рефакторить, часто видят заметный рост продуктивности — порядка 25% и более:

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

Это и есть «качество на скорости» в действии: непрерывное улучшение внутреннего качества кода, которое не конкурирует с поставкой, а поддерживает её.


Как вырастить культуру постоянного рефакторинга

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

1. Нормализуйте рефакторинг в процессе

  • Добавляйте задачи на рефакторинг в бэклог как полноценные рабочие элементы.
  • Разрешайте небольшие, оппортунистические улучшения как часть фич: «Оставь место чище, чем нашёл».
  • Включайте рефакторинг в Definition of Done там, где это уместно (например, «затронутый код покрыт тестами и в разумно чистом состоянии»).

2. Явно защищайте время

Если рассчитывать только на «свободное время» для уборки, её не будет.

  • Резервируйте повторяющиеся 90‑минутные блоки в каждом спринте или каждую неделю.
  • Тратьте их на самые болезненные «горячие точки» (ориентируясь на частоту изменений, количество ошибок или жалобы команды).

3. Делайте качество видимым

  • Отслеживайте и отмечайте улучшения: снижение цикломатической сложности, меньше багов в модуле, быстрее сборка.
  • Используйте code review, чтобы поощрять небольшие, постоянные улучшения.
  • Показывайте примеры «до/после» на командных встречах, чтобы продемонстрировать реальную пользу.

4. Лидируйте примером

Техлиды и сеньор‑разработчики должны:

  • Проводить свои 90‑минутные сессии и рассказывать, что они там делали
  • Уметь сказать «нет» костылям, которые создают долгосрочный хаос ради краткосрочной выгоды
  • Наставлять остальных в безопасных паттернах рефакторинга и тест‑дривен подходе к изменениям

Культура, в которой рефакторинг — это «просто то, как мы работаем», многократно усиливает эффект на уровне всей команды.


Как внедрить 90‑минутный рефакторинг на практике

Начать можно уже на этой неделе.

  1. Выберите болевую точку. Файл или модуль, который все обходят стороной или постоянно ругают.
  2. Запланируйте один 90‑минутный блок. Занесите его в календарь как встречу.
  3. Сначала напишите или улучшите тесты. Даже пара ключевых тестов лучше, чем ничего.
  4. Выберите один небольшой приём. Переименование, Extract Method или обёртка над зависимостью.
  5. Закоммитьте безопасное, инкрементальное улучшение. Не гонитесь за идеалом.
  6. Повторите на следующей неделе. Корректируйте подход по мере накопления опыта.

Через месяц вы заметите:

  • Самые страшные места в коде уже не так пугают.
  • Code review проходят легче.
  • Изменения уезжают в прод с меньшим количеством сюрпризов.

Через полгода ваша «легаси‑система» может всё ещё быть старой — но она станет понятной, тестируемой и гораздо менее болезненной в работе.


Заключение

Хаотичные проекты не чинятся одним героическим переписыванием. Они чинятся десятками — а то и сотнями — маленьких, безопасных 90‑минутных рефакторингов.

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

Начните с малого. Защитите 90 минут. Улучшите один острый угол.

А потом повторите на следующей неделе.

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

90‑минутный рефакторинг: как короткие сессии по уборке кода со временем превращают хаотичные проекты в поддерживаемые | Rain Lag