Что не является причиной для рефакторинга
Рефакторинг кода
Рефакторинг (Refactoring) кода это процесс изменения исходного кода программы, не затрагивающий её поведения и ставящий целью облегчить понимание её работы и/или упростить её дальнейшую поддержку. Обычно рефакторинг любой программы это внесение небольших изменений в её код, каждое из которых не меняет само поведение программы, но как-то упрощает и/или улучшает код. При этом очень важно, что бы рефакторинг выполнялся именно небольшими частями, т.к. когда программист меняет небольшую часть кода – ему значительно проще проследить за правильностью изменений и не наделать ошибок. Если же рефакторить сразу большие участки кода, то есть очень большая вероятность наделать ошибок, в результате которых программа может вообще перестать работать. Правда, то, что правки должны быть небольшими, вовсе не означает, что рефакторинг это лишь замена имён переменных или перемещение небольших участков кода из одного места программы в другое – рефакторинг позволяет полностью переработать всю программу, включая и логику её поведения, главное при этом – вносить изменения небольшими частями и тогда всё будет в порядке.
Цели рефакторинга
Наверное, Вы спросите меня, к чему в вообще это пишу? А к тому, что, если Вы внимательно смотрите исходники примеров исходных текстов к каждому уроку – Вы, наверное, заметили, что я часто меняю что-то в коде, иногда по мелочам, а иногда довольно заметно. Это потому что я сам применяю рефакторинг и хочу, что бы и у Вас это вошло в привычку.
Как я уже сказал – основная цель рефакторинга это сделать код проще и понятнее. Если после переработки код не стал лучше и понятнее – значит вы либо делали не рефакторинг, либо он не удался. При этом не путайте понятие рефакторинга с оптимизацией. В результате оптимизации код становится быстрее, но совсем не обязательно проще и понятнее, рефакторинг же служит именно для упрощения и улучшения читаемости кода.
Какой код надо рефакторить
Рефакторить можно и, часто, нужно, любой код – чаще всего надо просто полагаться на своё чутьё, если какой-то код кажется Вам не очень удачным или Вам кажется, что через неделю Вы уже забудете что делает тот или иной участок кода – скорее всего, этому коду требуется рефакторинг. Я попробую сформулировать основные правила, основываясь на которых, Вы можете понять, что ваш код требует переработки:
Когда применять рефакторинг?
На этот вопрос есть очень простой ответ: всегда. Занимайтесь рефакторингом при малейшей возможности – рефакторинг улучшает ваш код и, потратив на него сегодня 5 минут, Вы завтра сэкономите на поиске ошибок час. Самый простой метод применения рефакторинга такой: каждый раз, когда вы что-то меняете в программе – добавляете новую функцию, класс, просто объявляете переменную, или Вам надо поменять пару строк в какой-то функции – посмотрите на соседний код, находящийся выше и ниже того участка, с которым Вы работаете сейчас. Проверьте, может быть, в этот код можно внести какие-то изменения, что бы он стал ещё более понятным и/или простым, может быть Вы найдёте в нём какие-то логические ошибки или Вам в голову придёт при каком сочетании параметров код может дать сбой. Если Вы увидели что-то подобное, то займитесь рефакторингом. Но не следует скакать по коду из конца в конец – если Вы пришли что-то добавить в код или поменять – сначала сделайте то, зачем Вы пришли, а потом уже занимайтесь рефакторингом. Иначе в итоге Вы можете вообще забыть, зачем вы открыли исходник.
Когда заканчивать рефакторинг?
Постарайтесь не заболеть “синдромом рефакторинга”. Если Вы сделали код, посмотрели вокруг и всё Вас устраивает – не надо рыскать по коду в поисках “чего бы тут ещё зарефакторить”. Если Вам нечем заняться – сходите в спортзал, покатайтесь на машине, сходие в клуб или хотя бы просто попейте пивка. Делать рефакторинг только потому что Вам лень делать что-либо ещё – это очень плохая привычка.
Рефакторинг кода
Термин рефакторинг означает изменение исходного кода программы без изменения его внешнего поведения. Иногда под рефакторингом ошибочно подразумевают изменение кода с заранее оговоренными правилами отступа, перевода строк, внесения комментариев и прочими визуально значимыми изменениями, которые никак не отражаются на процессе компиляции, с целью обеспечения лучшей читаемости кода – это не рефакторинг, это просто подгонка кода под коде-стайл проекта.
Рефакторинг изначально не предназначен для исправления ошибок и/или добавления новой функциональности – он вообще не должен менять поведение вашей программы и именно это помогает избежать ошибок и, в будущем, облегчить добавление новой функциональности в программу. Рефаткоринг выполняется только для улучшения понятности кода и/или изменения его структуры, для удаления “мёртвого” (старого, уже не нужного, оставленного “на всякий случай”) кода – для того, чтобы в будущем код было легче поддерживать и развивать ваш код. Например, добавление в программу нового поведения может оказаться сложным с существующей структурой — в этом случае Вы можете сначала выполнить необходимый рефакторинг, а уже затем добавить новую функциональность.
Так же это может быть перемещение дынных из одного класса в другой, вынесение фрагмента кода из метода и превращение его в самостоятельный метод или даже перемещение кода по иерархии классов. Каждый отдельный шаг может показаться элементарным, но совокупный эффект таких малых изменений в состоянии радикально улучшить проект или даже предотвратить распад плохо спроектированной программы.
В экстремальном программировании и других подобных гибких методологиях, рефакторинг является неотъемлемой частью цикла разработки программы: разработчики то создают новые тесты и функциональность, то выполняют рефакторинг кода для улучшения его логичности и прозрачности, и снова циклически повторяют – новые тесты/код, рефакторинг, новые тесты/код, рефакторинг и т.д. Автоматическое юнит-тестирование позволяет программистам убедиться, что рефакторинг не разрушил существующую функциональность, т.е. что он был проведён правильно и без ошибок.
Помощь в рефакторинге
Существенную помощь в рефакторинге могут оказать IDE, плагины к IDE, а так же системы контроля версий. IDE и плагины к ней, например, могут подсвечивать разработчику те строчки кода, которые он изменил с момента последней записи исходного кода на диск. Таким образом, программисту становится визуально понятно, над каким кодом он уже поработал, а какой код пока не трогал – это позволяет, при проверке “в голове” правильности написания кода, сосредоточиться на более узком фрагменте исходного кода, а не на всей программе – если даже открытый файл в длину имеет 1000 и более строк, программист с помощью IDE легко найдёт те несколько строк программы, которые он только что поменял, даже если они находятся в разных концах исходного текста.
Системы контроля (а точнее оболочки для них) версий при этом позволяют программисту, помимо всего прочего, сравнивать его текущий код с предыдущими версиями этого же кода. Чаще всего они даже могут визуально оформить различия между текущим и прошлыми исходниками – например, подсветить новый код зелёным, удалённый код нарисовать красный и/или зачёркнутым, посмотреть всю историю развития кода, прочитать комментарии, которые делались при заливке апдейтов исходников в систему контроля версий и многое другое. В общем, эти системы очень удобная штука и они могут помочь в том числе и при проведении рефакторинга.
Вместо заключения или как научиться рефакторингу
Если честно, я не знаю как научиться рефакторингу. Могут лишь посоветовать Вам делать так же, как, в своё время делал я – просто акцентируйте внимание на рефакторинге, не забывайте о нём. Старайтесь всегда помнить о том, что ваша цель не только написать новый код, но и улучшить старый и задача улучшения при этом отнюдь не менее (а может даже и более) важная, чем создание нового кода. После пары-тройки недель ежедневных тренировок привычка рефакторить код станет вашей неотъемлемой частью и, после этого, качеству вашего кода позавидуют очень многие программисты, которые до сих пор не применяют рефаткоринг.
Возможно, Вам первое время будет казаться, что рефакторинг занимает слишком уж много времени и сил, и что именно он не позволяет Вам найти время на дальнейшее развитие вашей программы. Однако, это мнение ошибочно – на самом деле, рефакторинг наоборот, ускоряет развитие программы, т.к. со временем Вы всё больше и больше экономите времени на том, что отрефакторенный код будет для Вас же самих намного понятнее, удобнее, он будет содержать в разы меньше ошибок и, в итоге, на одних только исчезнувших ошибках или недочётках кода (которые могли бы потом привести к ошибкам), Вы будете экономить огромное количество времени. Кстати, этот факт подтверждён исследованиями таких больших и уважаемых компаний, как IBM, HP, Microsoft, Sony и многих других.
Что такое рефакторинг кода
Зачем разработчики на регулярной основе переписывают свой и чужой код, не добавляя туда ни одной новой функции и не исправляя ни одной ошибки?
Сейчас все расскажу. Поговорим о чудесной процедуре рефакторинга, спасающей тысячи программистов от бессонных ночей и психологических травм.
Что такое рефакторинг
Под рефакторингом подразумевается переработка уже существующего кода с целью упростить его. Упростить не с функциональной точки зрения, чтобы увеличить производительность ПО и сократить количество потенциальных ошибок, а с точки зрения визуального восприятия. Проще говоря, рефакторинг – превращение нагромождения кода в что-то удобоваримое и более читаемое, чтобы другие программисты не мучались в попытках понять, какая функция к чему относится, как с ней работать, какой результат она выдает и т.п.
Рефакторинг позволяет приблизиться к четкому соблюдению одного из важнейших правил написания кода – он должен быть «красивым» и лаконичным.
Определение Мартина Фаулера
Вопрос «Что такое рефакторинг?» часто возникает у программистов-новичков, а иногда и у более опытных разработчиков. Поэтому он регулярно всплывает на форумах в духе StackOverflow.
Там в качестве ответа на вопрос приводят цитату из книги «Refactoring: Improving the Design of Existing Code» за авторством Мартина Фаулера:
Рефакторинг – это контролируемая техника совершенствования структуры существующего кода. Суть рефакторинга заключается во внесении серии мелких изменения (с сохранением функциональности приложения), каждое из которых «слишком мелкое, чтобы тратить на него время». Тем не менее эффект от внесения всех этих изменений достаточно ощутимый.
Также в этой книге рекомендуется выполнять рефакторинг пошагово, чтобы исключить появление ошибок. А пользователи StackOverflow советуют каждое изменение сопровождать применением юнит-тестов. И хотя многие отрицают столь тесную связь этих двух операций, большинство опытных кодеров все же не упускают возможности задействовать тесты на любом из этапов разработки или модификации ПО.
Что не является рефакторингом?
Те, кто не углубляется в изучение терминологии, часто принимает за рефакторинг целую серию других действий, отчасти похожих на рефакторинг. В их числе:
простое переписывание кода,
улучшения функциональной составляющей ПО,
Первое имеет смысл при создании нового ПО или самотренировок.
Второе подразумевает поиск ошибок и их устранение, сам код при этом необязательно должен становиться проще или понятнее для других разработчиков. Цель дебаггинга – заставить программу работать корректно, не наплодив при этом новых ошибок.
Третье может быть связано с модификацией «читаемости» кода, но это необязательная составляющая. Важно сделать ПО лучше с пользовательской точки зрения, а не с точки зрения разработчика.
Четвертый термин чаще всего путают с рефакторингом, потому что они как раз иногда выполняются параллельно, но оптимизация – фокус на производительности программы. Код может стать даже сложнее, но ПО должно работать шустрее.
Но ни что из перечисленного выше не является рефакторингом, и зачастую каждая из процедур выполняется отдельно (за редким исключением, когда некорректное поведение ПО вызвано неправильно написанным кодом).
Зачем нужен рефакторинг?
Есть гласное правило для всех программистов – код должен быть лаконичным, хорошо структурированным и понятным для разработчиков, работающих с ним. Проблема в том, что написать такой код с первого раза – очень сложная задача. Каким бы опытным ни был программист, начальство заставит его спешить, заказчики будут менять требования по ходу разработки, а иногда код будет становиться непонятным из-за банального недосыпа. Более того, сами языки программирования регулярно совершенствуются и обретают новые возможности, позволяя заметно сократить количество кода. Поэтому и нужен рефакторинг.
Ожидаемые преимущества рефакторинга:
Улучшение объективной читаемости кода за счет его сокращения или реструктуризации.
Провоцирование разработчиков на более вдумчивое написание ПО с соблюдением заданной стилистики и критериев.
Подготовка плацдарма для создания переиспользуемых кусков кода.
Упрощение поиска ошибок в большом объеме кода.
Грамотно выполненный рефакторинг кода позволяет «продлить» жизнь проекту и сделать легче трудовую деятельность программистов из будущего.
В каких случаях нужен рефакторинг?
Есть ряд ситуаций, которые «кричат» о необходимости рефакторинга:
Попытка внести любое улучшение или добавление новой функции в приложение превращается в проблему для разработчиков, а сроки выполнения, на первый взгляд, несложных операций затягиваются на неадекватный срок из-за того, что база кода напоминает дебри.
Сроки добавления новых функций в приложение на постоянной основе становятся размытыми, потому что разработчикам приходится закладывать время на анализ кода.
Приходится выполнять идентичные процедуры в разных участках кода (объектах, классах) вместо того, чтобы внести изменение в одном классе, и оно возымело бы эффект в других участках ПО.
Код не соответствует общепризнанным в компании практикам оформления, из-за чего не может использоваться для дальнейшей разработки с учетом ранее установленных требований.
Впрочем, есть и другие, более индивидуальные факторы, подвигающие команду программистов на рефакторинг кода. Это зависит и от особенностей работы в конкретной компании, где серьезным поводом для рефакторинга может считаться даже неправильное количество пробелов в начале строки.
На какие аспекты кода направлен рефакторинг?
Четкой структуры рефакторинга не существует. Можно вносить любые изменения, улучшающие читаемость кода. Но обычно в поле зрения сразу же попадают следующие представители «плохого» кода.
Неиспользуемый код
В коде часто остается мусор в духе незадействованных переменных или методов. В базе кода висит текст, никак не влияющий на работу приложения, и его нужно удалить, чтобы не создавать путаницу. В этом, кстати, помогают современные тестовые редакторы, например VS Code.
Дубликаты
При длительной разработке сложного ПО можно замешкать и наплодить одинаковых функций или переменных. А еще в объектах могут существовать идентичные методы, но описанные в каждом отдельно. Такой код лучше вынести в родительский класс.
Переменные и функции названы неадекватно
К программистам предъявляются требования по оформлению кода, одно из ключевых – необходимость давать понятные имена переменным и функциям, чтобы без дополнительных комментариев можно было понять, что делает тот или иной метод. Никаких букв и случайных наборов символов.
Код, из которого невозможно что-либо понять
Избыточное количества текста в одном методе
Лучше поделить функцию на несколько составных частей, чем создавать одну слишком большую и трудночитаемую. Если ваша функция состоит из 70 строк кода – это не норма. Это же касается классов и других объектов.
Вот так может выглядеть функция преобразования текста в массиве
Та же функция, но описанная одной строкой
Избыточное количество комментариев
Если приходится пояснять каждую строчку кода, то с кодом что-то не так. Программист, который видит ваш код первый раз, должен разобраться в нем быстро, без необходимости начитывать целые тома комментариев и документации.
Некорректно оформленные куски кода
У кода есть правила визуального оформления. Нужно соблюсти корректное число пробелов от начала строки, правильно «вкладывать» одни компоненты в другие, соблюдать правила написания функций и циклов.
Для решения этих задач можно использовать специальные плагины. Расширение ESLint поможет писать красивый код, соответствующий общепринятым стандартам, а плагин Prettier самостоятельно расставит все запятые, пробелы и т.п., чтобы код отлично смотрелся в любом текстовом редакторе.
Методики рефакторинга
Разработчики и специалисты в области рефакторинга часто называют десятки различных тактик переработки кода, но почти все они четко привязаны к изменяемому компоненту (объекту, функции и т.п.), поэтому нет смысла их все перечислять. Обобщая, есть три основных способа выполнить рефакторинг:
Абстракция. Эта стратегия используется, когда нужно почистить дубликаты. Разработчиками придумываются абстрактные классы или другие классы высокого уровня, чтобы вынести туда повторяющиеся методы.
Фрагментация. Стратегия изменения кода с целью увеличить количество компонентов, но сделать сами компоненты меньше. Что-то в духе методик планирования задач, часто применяемых для повышения личной эффективности.
Сложности рефакторинга
Менять рабочий код всегда опасно. Даже мелкие изменения, кажущиеся суперлогичными и неопасными, иногда ломают приложение. Из-за этого рефакторинг и сопровождают тестами, потому что некоторые горе-программисты без особого внимания к деталям переписывают целые классы, а потом не могут включить ПО, потому что оно больше не работает.
Опытные разработчики рекомендуют следующие практики:
Делать рефакторинг как рутину. Не раз в полгода, а регулярно, но по чуть-чуть. Тогда он будет отнимать меньше времени и не будет отвлекать от более важных задач.
Не делать рефакторинг священной коровой, из-за которой откладываются более важные задачи в духе внедрения новых функций или дебаггинга.
Не пренебрегать рефакторингом, даже если трудитесь над всей базой кода самостоятельно. Если вы что-нибудь со временем забудете, то устанете разбираться в собственном коде. Не зря про это сочинили сотни однотипных шуток еще во времена bash.org.
Вместо заключения
Как видите, рефакторинг – это хоть и простое явление с точки зрения идеи, но необходимое для избежания задержек в разработке и сохранения нервных клеток коллег. Главное – сопровождайте каждый значимый этап рефакторинга тестами, чтобы сохранить «перерабатываемый» код в рабочем состоянии. Также стоит использовать системы контроля версий, каждое новшество отправляя отдельным коммитом в хранилище наподобие GitHub или GitLab. Это поможет в случае чего «откатить» неаккуратный рефакторинг и попытаться снова. Ведь самый понятный и читаемый в мире код все еще должен выполнять свои задачи, а не просто радовать взгляд искушенных кодеров.
Обучиться рефакторингу можно на курсах по программированию общего назначения у EPAM и Hexlet, а также на узкоспециализированных ресурсах в духе Refactoring Guru.
Рефакторинг
Содержание
Цели рефакторинга
Цель рефакторинга — сделать код программы легче для понимания; без этого рефакторинг нельзя считать успешным.
С другой стороны, нужно отличать рефакторинг от реинжиниринга, который осуществляется для расширения функциональности программного обеспечения. Как правило, крупные рефакторинги предваряют реинжиниринг.
Причины применения рефакторинга
Рефакторинг нужно применять постоянно при разработке кода. Основными стимулами его проведения являются следующие задачи:
Признаки плохого кода
Во многом при рефакторинге лучше полагаться на интуицию, основанную на опыте. Тем не менее имеются некоторые видимые проблемы в коде (англ. code smells ), требующие рефакторинга:
Рефакторинг кода
В программировании термин рефакторинг означает изменение исходного кода программы без изменения его внешнего поведения. В экстремальном программировании и других гибких методологиях рефакторинг является неотъемлемой частью цикла разработки ПО: разработчики попеременно то создают новые тесты и функциональность, то выполняют рефакторинг кода для улучшения его логичности и прозрачности. Автоматическое юнит-тестирование позволяет убедиться, что рефакторинг не разрушил существующую функциональность.
Иногда под рефакторингом неправильно подразумевают коррекцию кода с заранее оговоренными правилами отступа, перевода строк, внесения комментариев и прочими визуально значимыми изменениями, которые никак не отражаются на процессе компиляции, с целью обеспечения лучшей читаемости кода (см. code formatting).
Рефакторинг изначально не предназначен для исправления ошибок и добавления новой функциональности, он вообще не меняет поведение программного обеспечения [3] и это помогает избежать ошибок и облегчить добавление функциональности. Он выполняется для улучшения понятности кода или изменения его структуры, для удаления «мёртвого кода» — всё это для того, чтобы в будущем код было легче поддерживать и развивать. В частности, добавление в программу нового поведения может оказаться сложным с существующей структурой — в этом случае разработчик может выполнить необходимый рефакторинг, а уже затем добавить новую функциональность.
Это может быть перемещение поля из одного класса в другой, вынесение фрагмента кода из метода и превращение его в самостоятельный метод или даже перемещение кода по иерархии классов. Каждый отдельный шаг может показаться элементарным, но совокупный эффект таких малых изменений в состоянии радикально улучшить проект или даже предотвратить распад плохо спроектированной программы.
Методы рефакторинга
Наиболее употребимые [4] методы рефакторинга:
Изменение сигнатуры метода (Change Method Signature)
Суть изменения сигнатуры метода заключается в добавлении, изменении или удалении параметра метода. Изменив сигнатуру метода, необходимо скорректировать обращения к нему в коде всех клиентов. Это изменение может затронуть внешний интерфейс программы, кроме того, не всегда разработчику, изменяющему интерфейс, доступны все клиенты этого интерфейса, поэтому может потребоваться та или иная форма регистрации изменений интерфейса для последующей передачи их вместе с новой версией программы.
Инкапсуляция поля (Encapsulate field)
В случае, если у класса имеется открытое поле, необходимо сделать его закрытым и обеспечить методы доступа. После «Инкапсуляции поля» часто применяется «Перемещение метода».
Выделение метода (Extract Method)
Выделение метода заключается в выделении из длинного и/или требующего комментариев кода отдельных фрагментов и преобразовании их в отдельные методы, с подстановкой подходящих вызовов в местах использования. В этом случае действует правило: если фрагмент кода требует комментария о том, что он делает, то он должен быть выделен в отдельный метод. Также правило: один метод не должен занимать более чем один экран (25-50 строк, в зависимости от условий редактирования), в противном случае некоторые его фрагменты имеют самостоятельную ценность и подлежат выделению. Из анализа связей выделяемого фрагмента с окружающим контекстом делается вывод о перечне параметров нового метода и его локальных переменных.
Перемещение метода (Move Method)
Перемещение метода применяется по отношению к методу, который чаще обращается к другому классу, чем к тому, в котором сам располагается.
Замена условного оператора полиморфизмом (Replace Conditional with Polymorphism)
Условный оператор с несколькими ветвями заменяется вызовом полиморфного метода некоторого базового класса, имеющего подклассы для каждой ветви исходного оператора. Выбор ветви осуществляется неявно, в зависимости от того, экземпляру какого из подклассов оказался адресован вызов.
Проблемы, возникающие при проведении рефакторинга
Средства автоматизации рефакторинга
Технические критерии для инструментов рефакторинга:
Практические критерии для инструментов рефакторинга:
Примечания
См. также
Литература
Ссылки
Полезное
Смотреть что такое «Рефакторинг» в других словарях:
Рефакторинг баз данных — (англ. database refactoring) это простое изменение в схеме базы данных, которое способствует улучшению ее проекта при сохранении функциональной и информационной семантики[1]. Иными словами, следствием рефакторинга базы данных не может быть… … Википедия
Экстремальное программирование — Разработка программного обеспечения Процесс разработки ПО Шаги процесса Анализ • Проектирование • Программирование • Докумен … Википедия
Разработка через тестирование — Разработка программного обеспечения Процесс разработки ПО Шаги процесса Анализ • Проектирование • Программирование • Докумен … Википедия
Шаблоны проектирования — (паттерн, англ. design pattern) это многократно применяемая архитектурная конструкция, предоставляющая решение общей проблемы проектирования в рамках конкретного контекста и описывающая значимость этого решения. Паттерн не является законченным… … Википедия
Образы разработки — Шаблоны проектирования (паттерн, англ. design pattern) это многократно применяемая архитектурная конструкция, предоставляющая решение общей проблемы проектирования в рамках конкретного контекста и описывающая значимость этого решения. Паттерн не … Википедия
Паттерны проектирования — Шаблоны проектирования (паттерн, англ. design pattern) это многократно применяемая архитектурная конструкция, предоставляющая решение общей проблемы проектирования в рамках конкретного контекста и описывающая значимость этого решения. Паттерн не … Википедия
Шаблон проектирования — У этого термина существуют и другие значения, см. Паттерн. В разработке программного обеспечения, шаблон проектирования или паттерн (англ. design pattern) повторимая архитектурная конструкция, представляющая собой решение проблемы… … Википедия
Test-Driven Development — Разработка через тестирование (англ. test driven development) техника программирования, при которой модульные тесты для программы или её фрагмента пишутся до самой программы (англ. test first development) и, по существу, управляют её разработкой … Википедия
Smalltalk — Семантика: объектно ориентированная Появился в: Разработка начата в 1969 г., стал доступен для широкого использования в 1980 Автор(ы): Алан Кэй, Дэн Ингаллс, Xerox PARC Типизация данных: динамическая … Википедия
Исходный код — У этого термина существуют и другие значения, см. Исходный код (фильм). Исходный код HTML страницы со вставкой на языке JavaScript Исходный код (также исходный текст) текст компьютерной программы на каком либо языке программирования или… … Википедия