как правильно рефакторить код

4 простых способа рефакторинга кода

как правильно рефакторить код

Jun 12, 2020 · 4 min read

как правильно рефакторить код

Рефакторинг — это процесс обновления существующего кода без изменения его функционала. Существует множество причин рефакторить код, включая производительность, читаемость и масштабируемость в будущем.

Рефакторинг — это важная часть процесса для любого кодера, не только для продвинутых разработчиков. Для менее опытной аудитории рефакторинг является прекрасной возможностью изучать и отрабатывать новые приёмы, повышать свой уровень от сделано до сделано правильно!

Рассмотрим пять простых способов рефакторинга кода для начинающих в Python с пояснениями преимуществ и демонстрацией кода до и после.

Определение функций для повторяющихся задач

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

Функции предоставляют множество преимуществ, но с точки зрения рефакторинга сокращается объём кода, улучшается читаемость. Кроме того, если нужно обновить задачу, делать это понадобится только на одном участке — в определении функции.

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

Заметьте, что два блока почти идентичны. А что, если понадобится вычислить объём куба? Скорее всего мы скопируем цикл while, изменив имя переменной и приглашение к вводу.

После

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

Конструктор списков вместо цикла for

Конструктор списков — один из самых легендарных конструкторов Python. Конструктор списков является более чистой и быстрой реализацией в сравнении с многими простыми циклами for.

Существует множество преимуществ рефакторинга циклов for в конструкторы списков: код будет выполняться быстрее, существующие данные не будут меняться, кроме того, конструктор списков проще читать, как только вы к нему привыкаете.

Давайте рассмотрим два примера, один простой и второй немного посложнее.

В первом примере выберем нечётные числа из списка целых чисел.

После рефакторинга

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

Мы должны использовать вложенный цикл for вместе с временной переменной для хранения каждой строки перед вставкой в окончательную переменную.

После рефакторинга

Здесь немного расширено описание для лучшей читаемости, но все вычисления и вложенный цикл for обрабатываются в одном присвоении.

Логический оператор OR вместо условного оператора

Присвоение одного из двух значений может быть обработано с помощью простого оператора if:

Эти типы присвоений “или-или” традиционно могут выполняться с помощью условного оператора, объединяющего присвоения в один.

Структура условного оператора такова:

После

Логический оператор OR пытается присвоить первое значение. Если первое значение приводит к False —None, пустая переменная и т.д.—используется второе значение.

Этот код значительно проще читать, он позволяет эффективно устанавливать значение по умолчанию при присвоении переменной.

Функция enumerate() вместо range()

Цикл for в Python может сбивать с толку, особенно, если вы привыкли работать с другими языками программирования. Вашим первым порывом будет создать индексную переменную и использовать её для перебора списка.

Если вам очень нужны индексы каждого значения, используйте функцию enumerate() : перебор будет производиться по фактическому списку, и независимая переменная будет не нужна.

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

После рефакторинга

Функция enumerate() принимает два аргумента: итерируемое и начальное значение счёта, а возвращает текущее порядковое значение и элемент в итерируемом. Примечание: временная переменная счёта идёт первой в цикле for, а начальное значение счёта идёт вторым в вызове функции. Это распространённая ошибка.

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

Источник

4 простых способа рефакторинга кода

как правильно рефакторить код

Рефакторинг — это процесс обновления существующего кода без изменения его функционала. Существует множество причин рефакторить код, включая производительность, читаемость и масштабируемость в будущем.

Рефакторинг — это важная часть процесса для любого кодера, не только для продвинутых разработчиков. Для менее опытной аудитории рефакторинг является прекрасной возможностью изучать и отрабатывать новые приёмы, повышать свой уровень от сделано до сделано правильно!

Рассмотрим пять простых способов рефакторинга кода для начинающих в Python с пояснениями преимуществ и демонстрацией кода до и после.

Определение функций для повторяющихся задач

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

Функции предоставляют множество преимуществ, но с точки зрения рефакторинга сокращается объём кода, улучшается читаемость. Кроме того, если нужно обновить задачу, делать это понадобится только на одном участке — в определении функции.

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

Заметьте, что два блока почти идентичны. А что, если понадобится вычислить объём куба? Скорее всего мы скопируем цикл while, изменив имя переменной и приглашение к вводу.

После

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

Конструктор списков вместо цикла for

Конструктор списков — один из самых легендарных конструкторов Python. Конструктор списков является более чистой и быстрой реализацией в сравнении с многими простыми циклами for.

Существует множество преимуществ рефакторинга циклов for в конструкторы списков: код будет выполняться быстрее, существующие данные не будут меняться, кроме того, конструктор списков проще читать, как только вы к нему привыкаете.

Давайте рассмотрим два примера, один простой и второй немного посложнее.

В первом примере выберем нечётные числа из списка целых чисел.

После рефакторинга

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

Мы должны использовать вложенный цикл for вместе с временной переменной для хранения каждой строки перед вставкой в окончательную переменную.

После рефакторинга

Здесь немного расширено описание для лучшей читаемости, но все вычисления и вложенный цикл for обрабатываются в одном присвоении.

Логический оператор OR вместо условного оператора

Присвоение одного из двух значений может быть обработано с помощью простого оператора if:

Эти типы присвоений “или-или” традиционно могут выполняться с помощью условного оператора, объединяющего присвоения в один.

Структура условного оператора такова:

После

Логический оператор OR пытается присвоить первое значение. Если первое значение приводит к False —None, пустая переменная и т.д.—используется второе значение.

Этот код значительно проще читать, он позволяет эффективно устанавливать значение по умолчанию при присвоении переменной.

Функция enumerate() вместо range()

Цикл for в Python может сбивать с толку, особенно, если вы привыкли работать с другими языками программирования. Вашим первым порывом будет создать индексную переменную и использовать её для перебора списка.

Если вам очень нужны индексы каждого значения, используйте функцию enumerate() : перебор будет производиться по фактическому списку, и независимая переменная будет не нужна.

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

После рефакторинга

Функция enumerate() принимает два аргумента: итерируемое и начальное значение счёта, а возвращает текущее порядковое значение и элемент в итерируемом. Примечание: временная переменная счёта идёт первой в цикле for, а начальное значение счёта идёт вторым в вызове функции. Это распространённая ошибка.

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

Источник

Что такое рефакторинг кода и зачем он нужен

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

Рефакторинг — это переработка исходного кода программы, чтобы он стал более простым и понятным.

Рефакторинг не меняет поведение программы, не исправляет ошибки и не добавляет новую функциональность. Он делает код более понятным и удобочитаемым.

Например, вот фрагмент на Python, создающий список из строки:

При рефакторинге его можно упростить, применив конструктор списков:

Результат работы программы не изменился, но код стал проще, компактнее и понятнее.

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

как правильно рефакторить код

Программист, консультант, специалист по документированию. Легко и доступно рассказывает о сложных вещах в программировании и дизайне.

Зачем нужен рефакторинг

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

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

Чтобы решить все эти проблемы, делается рефакторинг программы. В новом проекте он нужен, чтобы:

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

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

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

Чем рефакторинг отличается от оптимизации

Рефакторинг — не оптимизация, хотя и может быть с нею связан. Часто его проводят одновременно с оптимизацией, поэтому понятия кажутся синонимами. Но у этих процессов разные цели.

Цель оптимизации — улучшение производительности программы, а рефакторинга — улучшение понятности кода. После оптимизации исходный код может стать сложнее для понимания.

После рефакторинга программа может начать работать быстрее, но главное — её код становится проще и понятнее.

Когда нужно срочно улучшать код

Признаки, показывающие, что назрела необходимость в рефакторинге:

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

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

Как делают рефакторинг

Рефакторинг — это маленькие последовательные улучшения кода. Чистить можно всё, но в первую очередь найдите эти проблемы:

После каждой правки посмотрите на соседние участки кода: возможно, их тоже стоит поправить и сделать понятнее. И на те участки кода, которые давно не редактировались, — они уже могли стать некорректными.

Код чистят и на этапе тестирования, когда всё уже готово и проверяется работоспособность программы. Тут разработчик выполняет требования тестировщиков и одновременно проводит рефакторинг.

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

В чём опасности рефакторинга

Мы всё-таки меняем рабочий код. Тут можно не только всё упростить, но и сильно напортачить. Небрежный рефакторинг может отбросить выполнение проекта на дни и недели.

Опасно делать рефакторинг не постоянно, а от случая к случаю. Соблазн сильно улучшить код становится невыносимым. Вы всё глубже закапываетесь в программу и копаете себе яму, в которой легко увязнуть.

Рефакторьте постоянно и по чуть-чуть.

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

Но всё равно нельзя пренебрегать усовершенствованием кода, потому что это лучший способ ускорить работу в будущем.

Хотите создавать эффективные приложения с минимальным количеством ошибок, чистым и понятным кодом? На наших курсах учат не только языкам программирования, но и процессу разработки: проектированию, рефакторингу, тестированию и дебагу.

Источник

Рефакторить или не рефакторить?

Мне нравится рефакторинг. Нет, не так. Я люблю рефакторинг. Не, даже не так. Я чертовски люблю рефакторинг.
Я не переношу плохой код и плохую архитектуру. Меня коробит, когда я пишу новую фичу, а в соседнем классе творится полный бардак. Я просто не могу смотреть на печально названные переменные. Иногда перед сном я закрываю глаза и представляю, что можно было бы улучшить в проекте. Иногда я просыпаюсь в три часа ночи и иду к ноутбуку, чтобы что-нибудь поправить. Мне хочется, чтобы на любой стадии разработки код был не просто кодом, а произведением искусства, на которое приятно смотреть, с которым приятно работать.

Если вы хоть немного разделяете мои ощущения, то нам есть о чём поговорить. Дело в том, что со временем что-то внутри меня начало подсказывать, что рефакторить всё подряд, везде и всё время — не самая лучшая идея. Поймите меня правильно, код должен быть хорошим (а лучше бы ему быть идеальным), но в условиях суровой реальности не всегда разумно постоянно заниматься улучшением кода. Я вывел для себя несколько правил о своевременности рефакторинга. Если у меня начинают чесаться руки что-нибудь улучшить, то я оглядываюсь на эти правила и начинаю думать: «А действительно ли сейчас тот момент, когда нужно нарефакторить?». Давайте порассуждаем о том, в каких же случаях рефакторинг уместен, а в каких — не очень.

как правильно рефакторить код
Дисклеймер. Скорее всего, многим захочется после прочтения поста сразу сказать: «Да это уже 600 раз обсуждалось!» или «Это же настолько очевидно, зачем же об этом писать?». Возможно, вы и правы, но только вот какой момент: в окружающем мире по-прежнему творится хаос. Вроде бы всем всё понятно, но на деле получается, что не так уж и понятно. Поэтому я думаю, что не будет слишком вредно ещё разок взглянуть на эту тему. Но если конкретно у вас проблем с рефакторингом нет, то можете просто пропустить этот пост, у вас уже всё хорошо.

Слишком ранний рефакторинг

Нецелевой рефакторинг

Скорее всего, у вас есть план разработки на ближайшее время. Вполне вероятно, что у вас есть сроки (даже если вы их поставили сами). Релизы нужно делать вовремя, затягивать разработку не стоит. Нужно контролировать себя, нужно заниматься теми вещами, которые входят в ваши непосредственные цели. Допустим, у вас есть кусок кода, который выглядит как полное… Ну, в общем, плохо выглядит. Но, продолжим наше допущение, вы с ним сейчас не работаете. Этот плохой кусок кода стабильно работает, успешно справляется со своими задачами и никак не связан с вашей текущей задачей. Ну так и не трогайте его! Да, вас может крайне печалить то обстоятельство, что на другом конце проекта всё очень плохо. Но заметьте, что прямо сейчас вам это никак не мешает. У вас есть текущие задачи, занимайтесь ими. Конечно, бывают задачи по улучшению кодовой базы, но нечасто — зачастую важнее добавлять новый функционал или фиксить баги. Концентрируйтесь на текущих задачах и не бросайте их из-за того, что где-то там что-то как-то не так.

Рефакторинг ради рефакторинга

Ок, вы пришли к выводу, что нужно обязательно отрефакторить часть проекта. Хорошо, давайте отрефакторим. Вроде бы запланированные улучшения выполнены, но тут возникает мысль: «А что я могу ещё улучшить? Ага, вон ту штуку». А после вон той штуки появится вот эта штука, а потом ещё одна, а потом ещё и т. д. Нужно понимать, что есть плохой код, есть хороший код, есть идеальный код. Последнего в большом проекте у вас никогда не будет. Это не значит, что не нужно к нему стремиться, но нужно понимать его недостижимость. Обычно задача стоит в написании хорошего кода, а не идеального. Допустим, после рефакторинга у вас получился вполне читаемый код, который работает более или менее очевидным образом, в котором нет костылей и которым не так сложно пользоваться. Задайте себе вопрос: «А может, пора остановиться?». Да, код можно улучшать. Причём в достаточно большом проекте его можно улучшать до бесконечности. Но вот прямо сейчас он справляется со своими функциями, им удобно пользоваться, он практически не вызывает у вас дискомфорта. Очень важно определить для себя приемлемое качество кода, после которого вы перестанете его улучшать (до тех пор, пока свойство приемлемости не будет утрачено). Вспомните, что есть ещё так много разных клёвых штук, которые можно дописать. Не нужно рефакторить ради самого рефакторинга, ради идеального кода. Нужно рефакторить, когда у вас есть веские причины на это: код сложно прочитать, код сложно поддерживать, код сложно развивать, код сложно использовать и т. п. Если ни одного «сложно» не возникает, то веских причин тратить время на рефакторинг у вас нет.

Рефакторинг за день до релиза

Бывает так, что релиз послезавтра/завтра/сегодня/должен был быть вчера (нужное подчеркнуть). Это важный момент в жизни проекта. Нужно уделить особое внимание тестированию, фиксам критических багов, финальным доделкам. Поверьте, это действительно плохая идея — перерабатывать кодовую базу (а ещё хуже — качественно перерабатывать) в тот момент, когда нужно отдавать проект в продакшн. Опытная практика подсказывает, что нужно зарелизиться, а потом с чистой совестью спокойно улучшать код. Некоторые спросят: «А почему?». Если такой вопрос возник, то, наверное, вам ещё не приходилось делать сложный рефакторинг. Подскажу: при переписывании код не всегда обязательно улучшается — иногда он может сломаться. Да что там сложный рефакторинг — бывает, поправишь один метод на пять строк, не уследишь за какой-нибудь зависимостью, а на другом конце проекта выползет бага, с которой сразу же встретятся ваши любимые пользователи. Вот вроде бы ничего плохого и не делаешь, а тут внезапно на тебя нападает зверь «Это было неочевидно» и топит тебя в пруду ложной первоначальной оценки. Хотя, может, это просто я такой плохой программист — люблю что-нибудь сломать. Вполне возможно, что вы всегда рефакторите всё абсолютно правильно и с полным контролем всего проекта. В таком случае я могу вас поздравить, но от совета с запретом предрелизного рефакторинга всё-таки не откажусь. Поверьте, за несколько дней рефакторинг никуда не убежит, а сон у всей команды будет чуточку, но спокойней.

Рефакторинг очень старого кода

Вопрос тяжёлый, очень тяжёлый. Ситуация: есть огромное количество ужасных строк кода, которые достались вам от старых разработчиков (возможно, этими старыми разработчиками были вы несколько лет назад, ещё до того, как научились писать всё правильно и сразу). Код приходится поддерживать. То там, то тут возникают костыли и дублирования, энтропия растёт. С каждым днём всё больше хочется выкинуть всё и переписать с нуля. В такой момент нужно очень хорошо подумать о рисках. Да, вполне вероятно, что в перспективе такая деятельность будет полезна. Но в какой именно перспективе и насколько полезна? Скорее всего, в процессе большого рефакторинга или переписывания отдельных частей вы замените старый работающий говнокод новым, идеально написанным кодом, но с багами. И вовсе не из-за того, что вы плохой программист и пишете плохо. Просто вы можете не знать этот код в достаточной мере. Вы можете не знать, почему автор написал всё именно так, а ведь причины могли быть. Иногда приходится писать очень странный и кривой код. Я могу придумать очень много примеров: подавление хитрых оптимизаций процессора, подстройка под баги сторонней библиотеки, подавление каких-нибудь многопоточных косяков и т. д. Я не говорю, что нельзя все эти проблемы решить нормально. Просто иной раз при переписывании казалось бы абсурдного кода на нормальный появляются баги. Да, можно было всё сделать нормально, но вы можете просто не осознать всё величие шалаша из костылей вместо палок, если не узнаете у автора кода, почему он написал именно так (а подобная возможность предоставляется далеко не всегда). Будьте осторожны, когда переписываете старый код, который понимаете не до конца (а особенно, если думаете, что понимать там нечего).

А когда рефакторить-то?

Вместо заключения

Всё вышеперечисленное является чисто субъективным обобщением опыта работы над рядом проектов. Разумеется, я покрыл далеко не все жизненные ситуации. В каждой команде свои требования к коду, свой бизнес-план и свои правила. Уверен, что у многих найдётся пяток историй из серии «А вот у меня был случай, когда все эти советы не работают». Это абсолютно нормально, так и должно быть. Нет универсальной серебряной пули для определения количества усилий на улучшение кода («Мы будем каждый день 47 минут 23 секунды заниматься рефакторингом — и всё у нас будет хорошо»). Вам нужно исходя из собственного опыта в вашем конкретном проекте, в вашей конкретной команде попытаться найти золотую середину между написанием нового кода и улучшением старого. Я агитирую только за то, чтобы ко всему было рациональное отношение без фанатизма («Зачем улучшать код, нового функционала от этого не появится» / «Нужно срочно весь код сделать идеальным, чтобы потом с ним можно было нормально работать»). Подходите разумно к распределению времени на работу над существующим кодом — и всё у вас будет хорошо.

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

Источник

Как рефакторить

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

как правильно рефакторить код

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

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

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

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

Есть два случая, когда после рефакторинга ломаются тесты:

Вы допустили ошибку при изменении кода. Тут всё просто — идите и исправьте ошибку.

Ваши тесты были слишком низкоуровневыми. Чаще всего это случается из-за того, что ваши тесты проверяют работу приватных методов классов.

В этом случае виноваты тесты и единственный способ это исправить — отрефакторить их или написать новые, более высокоуровневые. Такой ситуации можно вообще избежать, создавая тесты в стиле BDD.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *