90‑минутный рефакторинг: как короткие сессии по уборке кода со временем превращают хаотичные проекты в поддерживаемые
Как короткие, сфокусированные сессии рефакторинга могут постепенно превратить запутанный легаси‑код в поддерживаемую, качественную систему — без срывов сроков поставки.
90‑минутный рефакторинг: как короткие сессии по уборке кода со временем превращают хаотичные проекты в поддерживаемые
Вам не нужен трёхмесячный «полный перепис» системы, чтобы навести порядок в хаосе.
Вам нужно 90 минут.
Не один раз — а регулярно.
Короткие, жёстко ограниченные по времени сессии рефакторинга могут тихо превратить болезненный легаси‑код в систему, которую команда понимает, развивает и выпускает без страха. Если делать это правильно, это не тормозит поставку. Это её ускоряет.
В этом посте — как устроены 90‑минутные сессии рефакторинга, почему они так эффективны и какие практические приёмы можно безопасно применять даже в хрупких системах.
Почему работает рефакторинг с жёстким таймбоксом
Рефакторинг часто откладывают, потому что он кажется большим и рискованным. Менеджеры боятся: «Если дать разработчикам рефакторить, мы никогда ничего не выпустим». Разработчики боятся: «Если я это трону, всё сломается».
Таймбоксинг — например, блоки по 90 минут — снимает оба этих страха.
1. Он не даёт заботе о качестве убить сроки поставки
Таймбокс в 90 минут достаточно длинный, чтобы сделать что‑то ощутимое, и достаточно короткий, чтобы не развалить спринт.
Вы можете:
- Планировать одну‑две 90‑минутные сессии в неделю
- Привязывать их к текущей работе (например, к фиче или багфиксу)
- Держать их видимыми на доске (отдельные задачи типа «Refactor»)
Так рефакторинг не превращается в бесконечный марафон «сейчас мы всё починим». Вы останавливаетесь, когда останавливается таймер. Если изменение не закончено, вы:
- Коммитите небольшой, безопасный шаг вперёд
- Оставляете
TODOили заводите тикет на продолжение
Через недели и месяцы эти сессии складываются в реальные структурные улучшения — без просьб к стейкхолдерам профинансировать огромный и рискованный проект «глобального рефакторинга».
2. Он снижает психологический порог входа
«Сделать платёжную систему не такой ужасной» — звучит как неподъёмная задача.
«Потратить 90 минут, чтобы сделать только этот метод менее ужасным» — уже по силам.
Таймбоксинг превращает рефакторинг из драматичного события в рутинное обслуживание системы. Этот сдвиг в мышлении критичен, чтобы вы вообще начали это делать.
Инкрементальный рефакторинг: как безопасно эволюционировать легаси‑код
Выбросить всё и переписать заново — соблазнительно и опасно. Инкрементальный рефакторинг — скучный и мощный.
Инкрементальный рефакторинг — это:
- Много маленьких, осознанных изменений
- Каждый шаг оставляет систему рабочей
- Никаких «больших взрывов» и одномоментных переключений
Вместо:
«Через 3 месяца полностью заменим этот модуль»
Вы делаете:
«Каждую неделю делаем этот модуль чуть менее болезненным — и при этом не прекращаем релизить»
Признаки хороших инкрементальных изменений
За 90‑минутную сессию «хороший» рефакторинг — это:
- Сохраняющий поведение — система должна вести себя одинаково до и после изменений.
- Ограниченный по охвату — затрагиваете небольшой участок кода и не бросаетесь чинить всё, что видите.
- Обратимый — легко откатить, если тесты или прод покажут проблемы.
Примеры безопасных инкрементальных шагов:
- Переименовать запутанный метод и обновить все места вызова
- Разбить 200‑строчный метод на несколько небольших вспомогательных с понятными именами
- Заменить «магическое» число или строку на именованную константу или конфигурационный параметр
- Ввести небольшой, специализированный класс, который инкапсулирует одну грязную ответственность
Со временем эти маленькие шаги перекраивают даже самый уродливый легаси‑код во что‑то цельное и понятное.
Тестирование: ваша страховка при рефакторинге
Рефакторинг без тестов — как хирургия без диагностики.
Сильные практики тестирования превращают рефакторинг из рулетки в контролируемый, повторяемый процесс.
Что значит «сильное тестирование» в этом контексте
Не нужен 100% coverage, но вам нужно следующее:
- Быстрые автоматические тесты — чтобы их можно было гонять снова и снова в течение 90‑минутной сессии.
- Покрытие критичного поведения — потоки, где сбой особенно дорог: платежи, аутентификация, целостность данных.
- Индикаторы доверия — если тесты зелёные, вы с разумной уверенностью считаете, что не сломали ядро поведения.
Если вы стартуете с плохими тестами
В по‑настоящему запущенных системах рефакторинг часто начинается с… написания тестов.
Хороший шаблон:
- Определить конкретное поведение или баг.
- Написать тест, который фиксирует текущее (пусть даже ужасное) поведение.
- Запустить тест и посмотреть, проходит он или падает.
- Рефакторить маленькими шагами, постоянно прогоняя тестовый набор.
Первую 90‑минутную сессию вы вполне можете потратить только на characterization tests — тесты, которые документируют, что код делает сегодня, до очистки.
Потом эти тесты будут страховать вас, пока вы переформатируете код в следующих сессиях.
Практические паттерны рефакторинга для грязного кода
Ниже — простые приёмы, которые отлично подходят для 90‑минутных блоков рефакторинга.
1. Переименование ради ясности
Цель: чтобы код читался как объяснение предметной области.
Примеры:
doStuff()→calculateOrderTotal()flag→isEligibleForDiscountdataMap→customerIdToSubscription
Переименование — низкорисковое, но очень полезное для понимания изменение. Современные 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‑минутный рефакторинг на практике
Начать можно уже на этой неделе.
- Выберите болевую точку. Файл или модуль, который все обходят стороной или постоянно ругают.
- Запланируйте один 90‑минутный блок. Занесите его в календарь как встречу.
- Сначала напишите или улучшите тесты. Даже пара ключевых тестов лучше, чем ничего.
- Выберите один небольшой приём. Переименование, Extract Method или обёртка над зависимостью.
- Закоммитьте безопасное, инкрементальное улучшение. Не гонитесь за идеалом.
- Повторите на следующей неделе. Корректируйте подход по мере накопления опыта.
Через месяц вы заметите:
- Самые страшные места в коде уже не так пугают.
- Code review проходят легче.
- Изменения уезжают в прод с меньшим количеством сюрпризов.
Через полгода ваша «легаси‑система» может всё ещё быть старой — но она станет понятной, тестируемой и гораздо менее болезненной в работе.
Заключение
Хаотичные проекты не чинятся одним героическим переписыванием. Они чинятся десятками — а то и сотнями — маленьких, безопасных 90‑минутных рефакторингов.
Таймбоксированный, инкрементальный рефакторинг, подкреплённый надёжными тестами и практичными паттернами, позволяет вам планомерно улучшать внутреннее качество кода, не жертвуя поставкой фич. Со временем отдача становится очень ощутимой: выше продуктивность, меньше багов и кодовая база, которой команда не боится касаться.
Начните с малого. Защитите 90 минут. Улучшите один острый угол.
А потом повторите на следующей неделе.
Так хаотичные проекты постепенно превращаются в поддерживаемые системы — по одному маленькому рефакторингу за раз.