Рефакторинг — это процесс улучшения структуры, качества и читаемости кода без изменения его функциональности. При рефакторинге программу не переписывают, не добавляют новых функций и не исправляют ошибки. Простыми словами, рефакторинг — это «чистка» и упрощение кода.
Иногда этим термином называют процесс уменьшения технического долга в коде.
Технический долг — это метафора, которую предложил Говард Каннингэм для обозначения «грязного кода». Под техническим долгом стоит понимать нарастающий ком проблем:
- устаревшие фрагменты;
- фрагменты, работающие неэффективно или не работающие вовсе;
- отсутствие документации;
- плохо читаемый или трудный в поддержке код.
Зачем нужен рефакторинг
Если вы не разработчик, понять зачем нужно улучшать код можно с помощью аналогии, представив укладку кабеля.

Левая сторона на картинке выше — это то, что требует переработки, правая — там где ее уже провели.
Хаос «в коробочке» не значит, что левая сторона не работает, имеет ошибки или ее нужно выбросить и поменять на новую. Возможно, ей просто много лет, с ней работали много специалистов разного уровня или работники не придерживались никаких правил и структуры.
С кодом все то же самое. В самом начале, когда таких «проводов в коробочке» мало, с ними легко работать: любой новый специалист может с ходу разобраться, добавить новое не составляет труда, исправление ошибок занимает немного времени. Но со временем все копится как снежный ком и проблемы нарастают. А что если таких коробочек будет не одна, а сотни, тысячи или сотни тысяч? Тогда вопрос структуры и порядка в них встает ребром.

Тут и приходит на помощь рефакторинг. В рамках нашего сравнения его можно представить как поэтапное отключение и переподключение небольших секторов. Их отключают, содержимое полностью перебирают и заново укладывают в «коробочку». Затем идет проверка на работоспособность — тестирование, если говорить о коде. Если сектор работает, и что важно, — работает точно также как и до этого — изменения прошли успешно. И пока этот маленький сектор не заработает, переходить к другому или добавлять, менять что-либо в общей системе нельзя. Заработало, проверили, идем дальше.

В каких случаях нужен рефакторинг
- Множество одинаковых фрагментов вместо вызова одной функции.
- Слишком длинные или непонятные названия элементов программы.
- Избыточное количество временных переменных.
- Наличие неиспользуемого или «мертвого» кода.
- Слишком длинные методы или классы.
- Огромное количество комментариев, многие из которых только усложняют понимание;
- Части программы, которые заложили на будущее, но так и не довели до ума или они вовсе не понадобились.
- Нагромождение из неиспользуемых библиотек.
Понять, что в отделе разработки надвигается «чистка» можно и по косвенным причинам:
- Доработки занимают слишком много времени. Если каждая ваша задача на добавление малюсенькой новой функции отнимает у программистов долгие часы, дни, а то и месяцы, пора приводить код в порядок.
- Устранение ошибок требует долгого поиска проблемного участка. Если в программе косяк, а у программиста задергался глаз и появились новые седины, когда вы на это указали — пора рефакторить.
- Команда разработчиков или подрядчики не могут разобраться в хитросплетениях программ, «костыли» всюду и даже самые простые вещи уже не хотят работать без них.
- Много дублирующихся фрагментов и в каждый из них приходится вносить изменения при доработке и исправлении ошибок.
- Код не соответствует стандартам разработки. У многих организаций установлены собственные стандарты оформления кода для проектов, если их нет или разработчики им не следуют — в программах появляется хаос. Как пример можно использовать уже готовые внутренние стандарты Google, на текущий момент гайды имеют более 12 языков программирования.


Пример как делают рефакторинг
Рассмотрим несколько простых примеров программ, которые были переработаны.
1. Замена сложных операторов на методы
Задача: есть фрагмент кода, где используется сложный оператор (if-then/else или switch).
Решение: все сложные части оператора нужно выделить в отдельные методы.

2. Переименование непонятного метода
Задача: есть название метода getsmn(), которое не дает понимания что он делает.
Решение: переименуем метод так, чтобы из названия было понятно что он делает. Новое название — getSecondName().
3. Группировка фрагментов программы
Задача: есть фрагмент программы, который может быть сгруппирован.
Решение: вывести фрагмент в новый метод или функцию, вызвать его вместо старого фрагмента

Что не является рефакторингом
Иногда словом «рефакторинг» называют другие процессы, которые также являются усовершенствованием кода и помогают улучшить его качество. Рассмотрим их подробнее.
Дебаггинг
Дебаггинг — это исправление ошибок в коде. Исправление ошибки часто сопровождается изменением функциональности кода или внесением доработок. Рефакторинг наоборот не допускает изменения функций кода.
Оптимизация кода
Оптимизация кода — это изменение его структуры для увеличения производительности и скорости работы. При оптимизации код может стать менее понятным и читаемым для человека, но более приемлемым для компьютера. Отличие оптимизации от рефакторинга в том, что после первой код может стать еще более сложным для понимания, чем был изначально.
Полное переписывание кода
Если в ходе его изменений получился совсем другой продукт, с другим функционалом и структурой — это создание нового ПО.
Все эти методы улучшения кода не являются рефакторингом, но после каждой из процедур он может потребоваться.
Правила и методика рефакторинга
- Подготовить тесты до начала процедуры чистки кода и обращаться к ним после каждого, даже самого маленького, изменения. Самая лучшая схема: небольшое изменение - тест - небольшое изменение — тест.
- Не браться за изменение всего и сразу, править небольшие фрагменты. При редактировании больших кусков или всего сразу можно запутаться в изменениях, допустить ошибку и потратить кучу времени на ее поиск.
- Код должен быть понятен не только компьютеру, но и человеку. Не стоит вносить изменения, которые отрицательно отразятся на читаемости и усложнят поддержку работоспособности.
- Не вносить доработок и не дебажить во время рефакторинга. Велик шанс не найти потом концов.
- Бэкапы и еще раз бэкапы. Любое изменение кода должно подразумевать возможность откатиться назад без потери большого количества данных.
Техник и приемов в борьбе за лаконичный и понятный код можно выделить несколько:
- Составление методов
- Перемещение функций между объектами
- Организация данных
- Упрощение условных выражений
- Упрощение вызовов методов
- Решение задач обобщения
Сложности и ошибки рефакторинга
Часто у разработчиков, которые только пришли в компанию, или взяли новый проект, появляется острое желание все снести до основания и построить заново свой идеальный код, который точно будет работать лучше и быстрее предыдущего. Но обычно не все так просто. Мало кто специально пишет «грязный» код и щедро сдабривает его «костылями», часто на это есть причины и объяснения.
Рассмотрим самые частые ошибки и заблуждения:
- Пытаться переписать сразу весь код или пытаться сделать сразу идеально. Так не бывает, это просто недостижимо.
- Надеяться, что новые технологии, другой язык программирования или подключение библиотек решат имеющиеся проблемы. Переписав код по-другому, вы тоже получите ошибки, но уже другие.
- Искать проблему только в коде и надеяться что единоразовый рефакторинг все решит и проблема больше не повторится. Если проблема глубже, например: отсутствие правил и структуры у разработчиков, нехватка времени или дедлайны вчера, текучка кадров и постоянная смена исполнителей, то одним рефакторингом проблему не решить.
- Придя в проект или компанию пытаться с порога все переделать, чтобы было правильно, на ваш взгляд, конечно же. А это самое «правильно» для проекта или конкретного бизнеса может быть совсем другим. Не все проекты и потребности бизнеса можно закрыть, используя привычные или даже коробочные решения, иногда и «костыли» — это вынужденная мера. Основной совет: прежде чем что-то менять, разберитесь почему до вас сделали именно так, а не иначе.
- Проводить рефакторинг и одновременно внедрять новое. Есть шанс не справиться ни с тем, не с другим и испортить все и сразу.
Бывают случаи, когда в коде накопилось огромное количество ошибок и исправляя одну, появляется десяток, а то и сотня других. Если усилия по восстановлению работоспособности кода и его стабилизации не приносят успеха, но несут убытки, единственным решением будет написать код с нуля и прекратить поддержку старого.
Еще один момент, когда рефакторинга стоит избегать — приближение даты завершения проекта. В этом случае все улучшения и переработки кода стоит отложить на время, чтобы не навредить бизнесу и не сорвать сроки сдачи.
Коротко о главном
- Рефакторинг нужно делать постоянно, тогда он не будет отнимать кучу времени. Это не разовое решение. Нельзя один раз сделать идеально и расслабиться.
- Не стоит откладывать дебаггинг или внедрение новых функций , жертвуя при этом все время на рефакторинг.
- Даже если над кодом работает всего один программист, рефакторинг все равно нужен.
- Рефакторинг не поможет, если программа имеет кучу ошибок и не получается восстановить ее работоспособность. До рефакторинга программа должна работать.
Комментарии