Рефакторинг. Эпизод II. Механика процесса
На первый взгляд может показаться, что рефакторинг – дело не хитрое: меняй названия функций и объектов/структур/полей, разделяй/объединяй код. Но главный риск наивного подхода в том, чтобы в процессе пересборки движка он может перестать крутить колёса. Корректность небольших косметических изменений можно доказать внимательным чтением кода. Но что, если изменения в коде начинают распространяться далеко за границами того, что первоначально планировали изменить, и нарастают как снежный ком? О том, как научиться делать рефакторинг «at scale» и пойдёт сегодня речь.
Начнём мы с самой фундаментальной книги, которая не так давно получила новое издание.
«Refactoing. Improving the Design of Existing Code». Martin Fowler
Первая редация книги вышла ещё в 1999 году. С помощью неё инженеры научились продавать рефакторинг начальству и получили непосредственно методологию выполнения безопасных изменений в коде. Примеры кода были на Java.
Как заявил автор, вторая редакция книги была существенно переработана, чтобы охватить бОльшую аудиторию разработчиков. Для этого он сменил язык примеров на Java Script, убрал Java-специфичные рефакторинги, обобщил ранее описанные и добавил парочку новых. Но не пугайтесь: для разработчиков на других языках книга всё ещё полезна, Java Script специфики там немного.
Разбор вводного примера из книги самим Мартином Фаулером можно постмотреть на Youtube:
Как и раньше, в книге описаны:
- «bad code smells»,
- как писать базовые unit-тесты,
- для каждого рефакторинга: какую проблему решает, когда он применяется, как по шагам его выполнять,
- способы упрощения организации данных и ветвлений.
На мой взгляд, новая версия книги действительно стала более лёгкой в освоении, несмотря на свой почтительный размер.
«Working Effectively with Legacy Code». Michael Feathers
Если книга Фаулера – это «база» и «швейцарский нож» паттернов, то тут уже речь про тяжелые случаи рефакторинга запущенных кодовых баз. В ней разбирается часто встречающаяся проблема, когда к коду, на первый взгляд, просто невозможно подступиться, чтобы написать сперва для него тесты.
Чтобы решить эту задачу, автор ввёл термин «seam» (шов) и придумал несколько трюков, как в Java и C++ можно безопасно отковыривать тяжелые зависимости, мешающие тестам. Вдохновившись этим, наверно, можно придумать что-то похожее и в других языках. Практический пример применения подхода из книги можно посмотерть тут:
Книга очень сфокусирована на практику. Даже главы оформлены в виде типичных жалоб разработчика в духе: «Я хочу сделать изменение. Что мне тестировать?», «Моё приложение полностью состоит из внешних вызовов!», «У моего приложения нет структуры!».