Написано Дэйв Николетт

Если вы спросите группу разработчиков программного обеспечения о запахах кода, рефакторинге кода, работе с унаследованным кодом, погашении технического долга и исправлении или «спасении» существующего кода, вы услышите разные нюансы, но в целом они расскажут вам кое-что. как:

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

Может показаться, что технические специалисты в чем-то пришли к единому мнению. Это само по себе должно вызывать у вас подозрения.

Бурение вниз

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

  • Какие запахи кода вы чаще всего встречаете в существующих кодовых базах?
  • Какие рефакторинги вы чаще всего используете при исправлении устаревшего кода?
  • Расскажите историю из вашего опыта, когда технический долг создавался преднамеренно, как способ достижения тактической цели, на основе экономического анализа доступных вариантов, а потом погашался по плану?

Я узнал кое-что о текущем состоянии разработки программного обеспечения, задавая подобные вопросы.

Почти все разработчики могут перечислить стандартные модные словечки и канонические определения этих понятий. Но…

Удивительно много разработчиков не знают, что существуют специфические запахи кода, у которых есть имена, и специфические рефакторинги, у которых есть имена и которые предназначены для устранения конкретных запахов кода таким образом, чтобы ничего не ломалось. Большинство разработчиков считают все, что им не нравится, запахом кода, а любые изменения, которые они хотят внести, — рефакторингом.

Удивительно много разработчиков никогда не практикуют рефакторинг кода, точно так же, как музыкант отрабатывает гаммы или мастер боевых искусств отрабатывает формы. Единственный рефакторинг, который они когда-либо делали, был на реальном коде, на работе, в условиях дефицита времени. Они даже пытаются рефакторить настоящий код только на работе и в условиях дефицита времени.

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

Бурение глубже

Что произойдет, если мы снизим уровень детализации вопросов?

Изучите этот пример кода в течение нескольких минут. Хорошо? Теперь…

  • Какие конкретные запахи кода вы видите в этом коде?
  • Какие из них вы считаете серьезными проблемами?
  • Учитывая ограниченное время на исправление этого кода, какую проблему вы бы решили в первую очередь и почему?
  • Как бы вы подошли к этому исправлению, и каково ваше обоснование такого подхода?

Я узнал кое-что о текущем состоянии разработки программного обеспечения, задавая подобные вопросы.

Удивительно много разработчиков, кажется, ничего не имеют в виду, когда исследуют кодовую базу. Они импульсивно реагируют на все, что написано в коде по-другому. Удивительно, как много разработчиков могут смотреть на грубый код в течение нескольких минут и никогда не чувствовать запаха кода.

Даже те, кто делает распознавание определенных запахов кода, часто не могут решить, какие из них действительно стоит исправить, а какие можно безопасно оставить в покое.

Некоторые люди начинают удалять код или модифицировать API, не задумываясь (очевидно) о клиентах, которые могут существовать в мире и которые будут нарушены, если API изменится (см. Закон Хайрама). Другие начинают с удаления модульных тестов вместо их запуска. Другие запускают тесты, но не проверяют выходные данные, чтобы найти подсказки о том, где могут быть важные проблемы (например, в длительном тестовом примере).

Зачем практиковать?

Вы знаете все те повторяющиеся узоры, которые вы отрабатываете на своем любимом музыкальном инструменте, из материала вроде Арбанской книги? Знаете, вот так:

Какая от этого польза? Вы можете возразить, что ни одно музыкальное произведение не идентично серии повторяющихся паттернов. Да, это технически верно. Верно ли это полезно?

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

Вы знаете все эти медленные, плавные движения, которые вы делаете, когда практикуете форму тайцзи? Каждый шаг является приемом самообороны, если выполняется на полной скорости. Например, вот объяснение боевого применения Отпор обезьяне.

Какая от этого польза? Вы можете возразить, что ни один нападающий на улице не будет следовать точной последовательности шагов любого вида боевых искусств. Да, это технически верно. Полезно ли это?

Нападающие будут людьми. Таким образом, их тела будут двигаться так, как позволяет архитектура человеческого тела. Они не будут следовать какой-либо конкретной форме боевых искусств, но общая форма их движений будет в целом аналогична движениям в формах.

Чтобы отточить свои навыки разработчиков программного обеспечения, мы часто практикуем так называемые кодовые ката. Например, вот описание Прайм Фактор Ката. Обратите внимание, что это не случайный взлом. Мы следуем одной и той же последовательности шагов каждый раз, когда практикуем это ката.

Какая от этого польза? Вы можете возразить, что ни одно требование к программному обеспечению, которое мы, вероятно, внедрим на работе, не потребует вычисления простых множителей. Да, это технически верно. Полезно ли это?

Разные ката-коды представляют разные типы проблем программирования. Овладение некоторыми из них является хорошей подготовкой к реальной работе точно так же, как овладение рисунками на инструменте или формами в боевых искусствах является хорошей подготовкой к реальным ситуациям: многие задачи программирования имеют похожие «формы».

Почему бы и вам не заняться рефакторингом?

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

В принципе, это должно быть просто. Запахи кода — это структурные паттерны в исходном коде. Рефакторинг — это специфические изменения, которые пахнут адресным кодом. Разве мы не можем практиковать рефакторинг так же, как мы практикуем музыкальные паттерны или последовательности форм боевых искусств?

Поиск в Интернете найдет множество упражнений, объявленных как «ката рефакторинга», но это не совсем ката, потому что они не предписывают никакой последовательности действий. Даже если они не совсем соответствуют определению ката, большинство из них полезны для практики. Вот несколько примеров.

Позолоченная роза

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

Запах кода, показанный в коде Gilded Rose, — это сложное условное выражение, и основной рефакторинг, который следует использовать для его устранения, — это декомпозировать условное выражение, которое в основном состоит из ряда метод извлечения рефакторинга. И ситуация, и средство ее устранения очень распространены в существующих кодовых базах повсюду, что делает Gilded Rose практичным выбором для практики.

Ода коду

Майкл Уилан опубликовал пример кода для упражнения по рефакторингу Скотта Аллена, которое он назвал Ода коду, и опубликовал описание в своем блоге. Этот код демонстрирует проблемы, которые очень типичны для существующих кодовых баз.

Упражнение по Java Legacy

В LeadingAgile мы используем упражнение на основе Java для отбора технических тренеров, которое можно использовать на практике. Начальный код представляет собой часть приложения, в котором присутствует довольно много запахов кода. Если вы посмотрите на образец решения, вы можете найти некоторые последовательности рефакторингов, которые было бы полезно повторить в качестве практического упражнения. для борьбы с конкретными запахами кода.

Сочетания клавиш Катас

Пару месяцев назад я решил сделать IntelliJ IDEA своей Java IDE по умолчанию. Имея опыт работы с Eclipse, я хотел быстро освоить сочетания клавиш. Чтобы помочь себе в этом, я придумал несколько упражнений или ката для отработки сочетаний клавиш.

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

Без сомнения, вы можете найти много других полезных ката, которые помогут вам попрактиковаться в рефакторинге.

Об авторе:

Дэйв Николетт работает ИТ-специалистом с 1977 года. Он занимал различные технические и управленческие должности. С 1984 года он работал в основном консультантом, держась одной ногой в техническом лагере, а другой в лагере менеджеров… Подробнее.

Первоначально опубликовано на www.leadingagile.com 14 мая 2018 г.