Содержание
В запросе на слияние «попутно причесали» три модуля. Ревьюер не понимает, где смена поведения, а где переименование. Тесты зелёные на счастливом пути. В проде падает крайний случай, который жил в «очищенной» ветке. Знакомо?
Рефакторинг Мартина Фаулера (оригинал Refactoring) — не про «сделать красиво, пока тут». Книга про смену структуры без смены наблюдаемого поведения, маленькими шагами и с тестами. Ниже — разбор своими словами: как это выглядит в живых системах, где совет ломается, и что меняется с ИИ-ассистентами. Выжимка не заменяет оригинал.
Тезис книги
Рефакторинг — это дисциплина безопасных преобразований: вы улучшаете форму кода так, чтобы снаружи система вела себя так же. Фаулер отделяет этот режим от добавления функций. Смешивать оба в одном коммите — путь к «зелёным» тестам и красному проду.
Каталог приёмов и «запахи кода» — не эстетика ради эстетики. Это словарь, чтобы команда могла назвать движение («извлечь функцию», «ввести объект параметров») и повторить его предсказуемо. Второе издание (2018) ближе к современному JavaScript и типизации, но метод универсален: запах → именованный шаг → проверка → следующий шаг.
Ключевые идеи
Две шляпы: функция и рефакторинг
Что говорит автор. В один момент времени вы либо меняете поведение (новая возможность, исправление ошибки), либо меняете структуру при неизменном поведении. Переключайтесь сознательно. «Попутно почищу» — не рефакторинг, а риск, замаскированный под заботу о коде.
Как это выглядит в промышленном проекте. В монолите учётной системы метод проводки счёта на четыреста строк. Нужно добавить налоговые правила. Разработчик в том же запросе «разносит» метод, переименовывает поля и чуть меняет порядок проверок. Через неделю бухгалтерия ловит расхождение на нулевых суммах — а в диффе уже нельзя отделить структурный шум от смысловой правки.
Как это меняется с ИИ. Ассистент охотно смешивает шляпы: «упрощу и добавлю поле». Дифф выглядит опрятно, ревью скользит по переименованиям и пропускает сдвиг семантики. Правило то же: сначала структурные коммиты (или хотя бы отдельные коммиты в одном запросе), потом поведение — и явная проська модели: «не меняй наблюдаемое поведение».
Где совет может не работать. Крошечная правка в уже изолированном куске иногда дешевле двух проходов. Но как только зона общая или без тестов — две шляпы окупаются. Не путайте «маленький дифф» с «одним смыслом».
Что сделать уже сегодня. В следующем запросе разделите коммиты: сначала только структура, потом только поведение. В описании напишите одной строкой, какая сейчас шляпа.
Мой опыт. Я требую разделения не из педантизма, а потому что иначе ревью превращается в угадайку. Особенно когда правит агент: без двух шляп вы ревьюите рассказ модели о себе, а не изменение системы.
Если запомнить одну мысль — рефакторинг и новая функция в одном «попутно» почти всегда враги ясности.
Запахи кода — сигнал, не приговор
Что говорит автор. Длинный метод, дублирование, завистливая функция, длинный список параметров, условная логика, размазанная по файлам — это сигналы, что структура мешает изменениям. Запах не равен «плохому человеку» и не требует немедленного героизма. Он подсказывает, какой приём из каталога уместен.
Как это выглядит в промышленном проекте. «Божественный» метод проводки знает про налоги, скидки, журнал и отчёт. Каждый новый налог — ещё одна ветка if. Команда ругается на «плохой код», но правит внутри той же каши. Запах уже кричит: извлеки шаги, собери параметры в объект, замени ветвление полиморфизмом — после тестов.
Как это меняется с ИИ. Модель «лечит» запах косметикой: дробит на десятки однострочников или придумывает абстракцию с красивым именем. Запах уходит с радара метрик, связность падает. Полезнее назвать запах и приём: «здесь длинный список параметров — предложи ввести объект параметров, не трогая поведение».
Где совет может не работать. Охота на запахи как метрика команды («ноль длинных методов») плодит обёртки без смысла. Иногда запах — честная сложность домена на границе. Сначала спросите: мешает ли это следующей правке?
Что сделать уже сегодня. В файле текущей задачи назовите один запах вслух (или в комментарии к запросу). Не обязательно чинить всё — зафиксируйте сигнал.
Мой опыт. Запахи полезны как общий язык на ревью. «Тут длинный метод» лучше, чем «мне не нравится». Но я не открываю каталог на каждую строку: чиню то, что стоит на пути текущей истории.
Если запомнить одну мысль — запах указывает направление, а не требует суда.
Маленькие шаги и проверка после каждого
Что говорит автор. Рефакторинг идёт крошечными преобразованиями. После шага — компиляция / типы / тесты. Большой «улучшающий» скачок без промежуточных зелёных состояний — это уже переписывание под другим именем.
Как это выглядит в промышленном проекте. Команда решает «разнести» модуль оплаты за спринт. Три дня красных веток, потом один огромный запрос. Откатить невозможно, поиск коммита-виновника бесполезен. Альтернатива по Фаулеру: извлечь одну функцию, зелёный прогон, закоммитить; сдвинуть данные в объект параметров, снова зелёный; и только потом трогать налоговую ветку.
Как это меняется с ИИ. Агент любит «сделать хорошо за один проход»: переписать файл целиком. Вы получаете красивый текст и потерянный инвариант. Ограничивайте область: «сделай только извлечение функции X, остальное не трогай»; гоняйте тесты на каждый ответ модели, не на «когда закончит».
Где совет может не работать. Если нет никакой автоматической проверки, «маленький шаг» всё равно может молча сломать прод. Тогда сначала шов и характеризация (см. ниже), а не каталог ради каталога. В прототипе на выброс иногда рационален большой скачок — если вы честно не обещаете совместимость.
Что сделать уже сегодня. Возьмите один очевидный кусок и сделайте один именованный шаг. Запустите тесты. Закоммитьте. Остановитесь — даже если хочется «раз уж открыл».
Мой опыт. Маленькие шаги — лучшая страховка от собственного героизма. Я ломал прод не на «сложном алгоритме», а на «заодно привёл в порядок» без зелёной точки между правками.
Если запомнить одну мысль — между двумя зелёными состояниями должна помещаться одна мысль.
Тесты как страховка, не как ритуал
Что говорит автор. Без быстрой обратной связи рефакторинг превращается в азарт. Тесты фиксируют наблюдаемое поведение. В унаследованном коде часто нужны характеризационные тесты: сначала зафиксировать «как есть», потом менять форму.
Как это выглядит в промышленном проекте. Модуль расчёта без юнитов; все боятся трогать. Вместо большого переписывания — один тест на текущий вывод для типового счёта и одного краевого случая. Только после этого — извлечение функций. Сравнение: «большой взрыв» нового сервиса vs постепенное улучшение на месте со страховкой.
Как это меняется с ИИ. Модель пишет тесты к новому коду, который сама же предложила — зелёные и бессмысленные. Или «упрощает» и выкидывает проверку на null, которую не видела в сценариях. Требуйте: сначала тест, закрепляющий текущий вывод; потом рефакторинг; дифф теста без смены ожиданий — красный флаг.
Где совет может не работать. Полное покрытие перед первой правкой — фантазия в огромном монолите. Берите узкий пояс вокруг зоны изменения. UI и некоторые интеграции требуют другого контура — но принцип «есть оракул поведения» тот же.
Что сделать уже сегодня. Перед правкой страшного метода добавьте один характеризационный тест на фактический результат (даже снимок вывода), без переписывания дизайна.
Мой опыт. Фаулер здесь стыкуется с книгой Фезерса про унаследованный код: швы и характеризация — входной билет. С «Чистым кодом» наоборот: «красота» без тестов — косметика, которую стыдно откатывать, когда прод уже горит.
Если запомнить одну мысль — тест покупает право менять форму.
Каталог приёмов — словарь команды
Что говорит автор. Именованные движения (Extract Function, Move Function, Replace Conditional with Polymorphism, Introduce Parameter Object и десятки других) дают общий язык. Не нужно зубрить весь каталог. Нужно уметь узнать ситуацию и выбрать ход, как шахматист узнаёт типовую позицию.
Как это выглядит в промышленном проекте. Перед добавлением налоговых правил в проводку: извлечь шаги расчёта, собрать разрозненные аргументы в объект параметров, вынести вариации налога в отдельные стратегии — каждый шаг из каталога, каждый с зелёными тестами. Ревьюер читает не «магический дифф», а последовательность известных ходов.
Как это меняется с ИИ. Просите модель не «порефакторь красиво», а «примени извлечение функции к блоку строк 80–120». Каталог сужает пространство ошибок. Без имени приёма ИИ изобретает свой диалект «чистоты» — и вы снова в двух шляпах сразу.
Где совет может не работать. Карго-культ: извлечение функции до однострочников, «полиморфизм» на три ветки, которые меняются раз в год. Каталог — набор инструментов, не квесты на 100%. Устаревшие примеры первого издания на Java не отменяют приёмы — меняйте синтаксис, оставляйте смысл.
Что сделать уже сегодня. Выберите один приём из каталога (хотя бы извлечение функции) и примените его один раз в зоне задачи, с зелёными тестами.
Мой опыт. Словарь важнее энциклопедии. Junior выигрывает, когда может сказать «давай введём объект параметров» вместо «тут как-то слишком много всего». Senior выигрывает, когда знает, какой ход не делать.
Если запомнить одну мысль — назовите ход, прежде чем двигать код.
Когда рефакторить (и когда не трогать)
Что говорит автор. Эвристики вроде правила трёх: терпите дублирование до третьего раза, потом обобщайте. Рефакторьте перед тем, как наращивать беспорядок; после того, как поняли код. Не рефакторьте «всё подряд», когда горит срок и нет страховки.
Как это выглядит в промышленном проекте. Новый налог в том же божественном методе — классический момент «сначала структура, потом ветка». Наоборот, косметический проход по модулю «на будущее» без ближайшей истории часто умирает в конфликте с чужим запросом. Большой взрыв «перепишем биллинг» vs улучшение на месте: второе чаще переживает квартал.
Как это меняется с ИИ. Модель всегда готова рефакторить «на всякий случай». Ваш фильтр: есть ли ближайшее изменение поведения, которое станет проще? Есть ли тест? Если нет — отказ. ИИ хорошо ускоряет осознанный ход и плохо заменяет суждение «сейчас не время».
Где совет может не работать. Правило трёх — не закон физики. В безопасности и деньгах иногда обобщают со второго раза. В выбросном прототипе — и с пятого не надо. Контекст важнее мантр.
Что сделать уже сегодня. Перед следующей нетривиальной правкой спросите: «что мне мешает изменить это безопасно?» Если ответ — структура, запланируйте один шаг рефакторинга до фичи.
Мой опыт. Лучший рефакторинг — тот, что оплачен ближайшей историей. Худший — «приведи весь сервис к идеалу», пока продукт ждёт одну галку.
Если запомнить одну мысль — время рефакторинга привязано к следующей правке, не к абстрактному стыду за код.
На практике
На проверке кода
Спрашивайте:
- Это одна шляпа или две сразу?
- Есть ли зелёная точка между шагами?
- Какой запах и какой приём названы?
- Не сдвинуто ли поведение под видом переименования?
В запросе с ИИ-агентом
Требуйте узкий приём, тест до и после, маленький дифф. Ревьюйте смысловые строки отдельно от «шума красоты». Если агент выкинул проверку на пустое значение «для простоты» — это не рефакторинг.
С унаследованным кодом
Сначала шов и характеризация, потом каталог. Иначе вы рефакторите на удачу. Серия и Фезерс про это прямо говорят — см. подборку.
Кому какая идея полезнее
| Идея | Junior | Middle | Senior |
|---|---|---|---|
| Две шляпы | ★★★★★ | ★★★★★ | ★★★★ |
| Запахи как сигнал | ★★★★ | ★★★★★ | ★★★★ |
| Маленькие шаги | ★★★★★ | ★★★★★ | ★★★★ |
| Тесты / характеризация | ★★★★★ | ★★★★★ | ★★★★★ |
| Каталог приёмов | ★★★★ | ★★★★★ | ★★★★ |
| Когда не трогать | ★★★ | ★★★★ | ★★★★★ |
Оценки — ориентир для разговора, не таблица истины.
Ограничения и критика
Каталог огромен: попытка выучить всё подряд редко приживается. Примеры первого издания стареют; второе ближе к JS, но ваш стек всё равно другой — переносите метод, не копируйте синтаксис. Без культуры тестов книга легко превращается в оправдание больших опасных диффов («мы же рефакторили»).
Короткое сравнение. Refactoring — как безопасно менять форму. «Чистый код» — каким код выглядит локально (и там больше догм). Фезерс — что делать, когда тестов ещё нет. Предметно-ориентированное проектирование — куда рефакторить смысловую модель, а не только функции. «Программист-прагматик» — привычки вокруг изменений; Фаулер даёт микро-механику шага.
Читайте каталог как словарь ходов, не как чеклист «закрыть все запахи за спринт».
Кому читать
Стоит, если вы трогаете промышленный код чаще, чем пишете с нуля; если ревьюете чужие и агентские запросы; если команда спорит о «красоте», но ломает поведение.
Можно отложить углубление в каталог, если вы ещё не пишете тесты вообще — сначала страховка и маленькие шаги, потом энциклопедия приёмов.
Осторожно, если ищете оправдание большому переписыванию: книга как раз против подмены рефакторинга переписыванием.
Что сделать сегодня
- В следующем запросе разделите коммиты: рефакторинг, затем поведение.
- Назовите один запах в текущем файле и примените один приём каталога при зелёных тестах.
- Добавьте один характеризационный тест перед правкой страшного метода.
- Если просите ИИ извлечь функцию — сначала закрепите тест на текущий вывод.

