- КОАП

Что такое рефакторинг кода и для чего он нужен

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

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

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

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

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

  • Не забывайте делиться опытом, проводить код-ревью, выбирать единые инструменты и принимать соглашения в команде.

  • Вкладывайтесь в процесс. Внедряйте и автоматизируйте процессы по контролю качества кода на любом из этапов разработки.

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

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

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

Ожидаемые преимущества рефакторинга:

  • Улучшение объективной читаемости кода за счет его сокращения или реструктуризации.

  • Провоцирование разработчиков на более вдумчивое написание ПО с соблюдением заданной стилистики и критериев.

  • Подготовка плацдарма для создания переиспользуемых кусков кода.

  • Упрощение поиска ошибок в большом объеме кода.

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

Разработчики и специалисты в области рефакторинга часто называют десятки различных тактик переработки кода, но почти все они четко привязаны к изменяемому компоненту (объекту, функции и т.п.), поэтому нет смысла их все перечислять. Обобщая, есть три основных способа выполнить рефакторинг:

  • Red-Green-Refactor. Это некий аналог «На старт, внимание, марш!». Находим кусок кода для переработки, пишем юнит-тест, переходим к переписыванию.

  • Абстракция. Эта стратегия используется, когда нужно почистить дубликаты. Разработчиками придумываются абстрактные классы или другие классы высокого уровня, чтобы вынести туда повторяющиеся методы.

  • Фрагментация. Стратегия изменения кода с целью увеличить количество компонентов, но сделать сами компоненты меньше. Что-то в духе методик планирования задач, часто применяемых для повышения личной эффективности.

Проблемы рефакторинга

Изначально понятие рефакторинга (refactoring) сформировалось применительно к Smalltalk, а потом уже концепция постепенно распространилась среди сторонников других языков программирования. Собственно, рефакторинг — это уже неотъемлемый элемент процесса разработки структуры приложений (framework development). Речь идет именно о рефакторинге, когда структурщики работают над иерархией классов и сокращением кодов.

Грамотные специалисты понимают, что слёту хорошую структуру не создать, она совершенствуется в ходе работы, как говорится «на опыте». И еще они знают, что чаще речь идет об улучшении читаемости и модификации старого кода (а не о создании нового). Вот тут и вступает в силу рефакторинг, применимый и для всего ПО, и отдельно для структур (frameworks).

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

Правила и методика рефакторинга

  1. Подготовить тесты до начала процедуры чистки кода и обращаться к ним после каждого, даже самого маленького, изменения. Самая лучшая схема: небольшое изменение — тест — небольшое изменение — тест.
  2. Не браться за изменение всего и сразу, править небольшие фрагменты. При редактировании больших кусков или всего сразу можно запутаться в изменениях, допустить ошибку и потратить кучу времени на ее поиск.
  3. Код должен быть понятен не только компьютеру, но и человеку. Не стоит вносить изменения, которые отрицательно отразятся на читаемости и усложнят поддержку работоспособности.
  4. Не вносить доработок и не дебажить во время рефакторинга. Велик шанс не найти потом концов.
  5. Бэкапы и еще раз бэкапы. Любое изменение кода должно подразумевать возможность откатиться назад без потери большого количества данных.

Что такое рефакторинг программного обеспечения?

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

Читайте также:  Администрация Даниловского муниципального района

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

При проведении рефакторинга важным предварительным условием является наличие надежных тестов.

Правила разработки тестов

  • Делайте все тесты полностью автоматическими, так чтобы они проверяли собственные результаты.
  • Комплект тестов служит мощным детектором ошибок, резко сокращающим время их поиска.
  • Чаще запускайте тесты. Запускайте тесты при каждой компиляции — каждый тест хотя бы раз в день.
  • Получив сообщение об ошибке, начните с создания теста модуля, показывающего эту ошибку.
  • Лучше написать и выполнить неполные тесты, чем не выполнить полные тесты.
  • Подумайте о граничных условиях, которые могут быть неправильно обработаны, и сосредоточьте на них свои тесты.
  • Не забывайте проверять, чтобы в случае возникновения проблем генерировались исключительные ситуации.
  • Опасение по поводу того, что тестирование не выявит все ошибки, не должно помешать написанию тестов, которые выявят большинство ошибок.

Есть еще несколько методов, использование которых поможет провести грамотный refactoring программы и сделать ее структуру более понятной:

  • Непонятные имена. Все названия классов, методов, переменных и других конструкций кода должны иметь интуитивно-понятные наименования, по которым можно понять, что именно они делают. Следование правилу сделает структуру понятной для других разработчиков.
  • Большие методы и классы. Громоздкие конструкции сокращаются путем вынесения фрагментов в компактные методы и классы, которые правильно ссылаются друг на друга.
  • Длинные списки параметров. Здесь работает аналогичное правило, что и выше. Число аргументов сокращается максимум до четырех-пяти, иначе структура программы будет сложной.
  • Цепочки сообщений. Метод любого объекта должен ссылаться только на собственные либо переданные извне параметры, а также на те участки кода, к которому есть прямой доступ. Это правило называется законом Деметры. Если в программе это не так, нужно перепроверить все связи и правильно их настроить.
  • Статика. Обилие статических переменных увеличивает непредсказуемость программы и делает код более процедурным, нежели объектно-ориентированным. Чтобы избежать этого, разработчик должен инстанцировать объекты, позволяя им управлять данными так, как им нужно.
  • Универсальные объекты. Такие конструкции, имеющие доступ к другим универсальным участкам программы, нарушают закон Деметры и увеличивают связность системы. Это не идет на пользу приложению, поэтому в процессе рефакторинга важно инжектировать только необходимые зависимости.

Увеличить эффективность и скорость рефакторинга помогут хорошие тесты — функциональные, интеграционные и unit-тесты. Необходимо перепроектировать программу небольшими итерациями, после каждого такого шага проводить тестирование, и, если все в порядке, продолжать процедуру.

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

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

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

  • Правило 3 ударов


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

  • Делайте рефакторинг, когда добавляете новую функцию
  • Делайте рефакторинг, если требуется исправить ошибку
  • Делайте рефакторинг при разборе кода

Поддержка рефакторинга руководством

Инвестиции в инфраструктуру и техническое обслуживание могут быть непопулярны в вашей компании.

Легко утверждать, что время, потраченное на рефакторинг, — это время, проведенное вне новой работы.

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

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

Как происходит рефакторинг

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

  • дублирование – одинаковый код выполняет одни и те же действия в нескольких местах программы. Данную часть лучше вынести в отдельную функцию;
  • слишком длинные классы – если длина превышает 30 строк, лучше разбить его на несколько мелких классов;
  • мертвый код – после внесения изменений переменная, класс или метод больше не используется, но код остается нетронутым. От таких участков надо сразу избавляться. Довольно часто такую ситуацию можно встретить в сложных условных конструкциях, где одна из веток никогда не исполнялась, но соответствующий код так и не был удален;
  • некорректно названные переменные – имена должны сообщать, что хранится в данной переменной и для чего она существует. Это правило также справедливо для функций и классов. Например, переменную, обозначающую минимальную длину не стоит называть «a» или «b», правильнее будет minLength;
  • слишком длинные методы и функции – все то же самое, что и с классами. Оптимальный размер – 20-30 строк, не более. Если сократить не получается, лучше разделить функцию на несколько небольших процедур;
  • обилие параметров у методов или функций – чем их больше, тем легче запутаться. Если каждый параметр действительно необходим, их стоит вынести в отдельную структуру, у которой должно быть понятное имя;
  • большое количество комментариев – ими стараются скрыть недостатки плохого кода. Если при написании какого-то участка, появляется желание написать поясняющий текст, стоит попробовать переписать код таким образом, чтобы он стал более понятен. Программа, переполненная комментариями, плохо воспринимается.После внесения правок, стоит обратить внимание на другие участки кода, прежде всего на те, которые давно не редактировались. Высока вероятность того, что они стали некорректными и требуют исправления.
Читайте также:  Идёт ли стаж по трудовому договору без трудовой книжки

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

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

Наиболее четко определение термина указывает Мартин Фаулер в своей знаменитой книге «Refactoring: Improving the Design of Existing Code». Так указано, что рефакторинг является контролируемой техникой оптимизации исходного кода. Его цель заключается в достижении лаконичности и простоты восприятия за счет внесения небольших корректировок, при этом работать утилита продолжает, как раньше.

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

Правила проведения рефакторинга

Еще до переработки нужно определиться со следующими моментами:

  • Предпочтительными задачами

  • Темпами развития

  • Существованием реальной потребности в оптимизации

  • Уже используемыми инструментами работы с техническим долгом

  • Ранее предпринятыми проверками

  • Наличием навыков для внесения изменений в code

  • Действующими в компании стандартами оформления документации

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

  • Методами исправления, способными обеспечить максимальную отдачу

Разная квалификация разработчиков

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

Сильный программист может быть в 20 раз продуктивнее слабого. Плюс слабый программист порождает проблемный код. Если вы сажаете потом за доработку этого кода сильного программиста, он будет работать медленнее!

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

Какой код надо рефакторить

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

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

    В вашей программе есть очень длинные методы/функции. Как правило, человек не может полностью воспринимать и оценивать правильность кода, если этот код занимает больше 2-3 десятков строк. Такие методы и функции следует разделять на несколько более мелких и делать одну общую функцию, которая будет последовательно вызывать эти методы. Никогда не пытайтесь сократить длину кода записывая по несколько операторов в одной строке!!! Это один из самых худших вариантов организации программы и я вам даю 100% гарантию, что такой код в итоге приведёт к ошибкам!

    Длинный список параметров функции/метода/конструктора. Большое количество параметров обычно не только усложняет понимание того, что, что делает этот метод или функция, но и усложняет понимание кода, использующего эти функции. Если Вам реально нужно, что бы функция принимала очень много параметров – просто вынесите эти параметры в отдельную структуру (либо класс), дав этой структуре разумное и понятное имя, и передавайте функции ссылку (либо указатель) на объект этой структуры или класса.

    Большие классы так же требуют рефакторинга. Если у Вас в программе есть один или несколько больших (больше пары-тройки десятков строк кода) классов, Вам следует немедленно разделить их на более мелкие и включить объекты этих классов в один общий класс. Причина этого та же самая, что и в предыдущем пункте.

    Слишком много временных переменных так же являются признаком плохого кода, который требует рефакторинга. Как правило, много временных переменных встречаются в излишне “раздутых” функциях – когда Вы сделаете рефакторинг таких функции, скорее всего и количество временных переменных в каждой из них станет меньше и код станет значительно понятнее и удобнее

    Много “беспорядочно” хранящихся данных, которые связаны логически и их можно было бы объединить в структуру, либо класс. Логически связанные данные всегда стоит хранить в структурах/классах, даже если это всего 2-3 переменных – хуже от этого никому не станет, а вот код станет значительно понятнее.

    Если объекты одного класса слишком много/часто обращаются к (ссылаются на) данным другого объекта – Вам следует пересмотреть функционал объектов. Возможно, Вы приняли неверное архитектурное решение и его надо поменять как можно раньше, пока эта ошибка не расползлась по всему коду.

    Старайтесь не хранить слишком много глобальных переменных. Если же Вам и в самом деле нужно именно столько и никак не меньше глобальных объектов – попробуйте хотя бы сгруппировать их в структуры/классы, либо хотя бы просто вынесите их в отдельный namespace – тогда шанс того, что вы случайно используете какую-то переменную по ошибке, станет значительно ниже.

Читайте также:  Какие документы нужны для завещания квартиры в 2022 году

Рефакторинг и проектирование

Рефакторинг играет особую роль в качестве дополнения к проектированию. Если заранее подумать об архитектуре программы, то можно избежать последующей дорогостоящей переработки. Многие считают, что проектирование важнее всего, а программирование представляет собой механический процесс. Аналогией проекта служит технический чертеж, а аналогией кода — изготовление узла. Но программа весьма отличается от физического механизма. Она значительно более податлива и целиком связана с обдумыванием. Как говорит Элистер Кокберн (Alistair Cockburn):
«При наличии готового дизайна я думаю очень быстро, но в моем мышлении полно пробелов».

Существует утверждение, что рефакторинг может быть альтернативой предварительному проектированию. В таком сценарии проектирование вообще отсутствует. Первое решение, пришедшее в голову, воплощается в коде, доводится до рабочего состояния, а потом обретает требуемую форму с помощью рефакторинга. Такой подход фактически может действовать. Мне встречались люди, которые так работают и получают в итоге систему с очень хорошей архитектурой. Тех, кто поддерживает «экстремальное программирование» [ Beck , XP ], часто изображают пропагандистами такого подхода.
Подход, ограничивающийся только рефакторингом, применим, но не является самым эффективным. Даже «экстремальные» программисты сначала разрабатывают некую архитектуру будущей системы. Они пробуют разные идеи с помощью CRC-карт или чего-либо подобного, пока не получат внушающего доверия первоначального решения. Только после первого более или менее удачного «выстрела» приступают к кодированию, а затем к рефакторингу. Смысл в том, что при использовании рефакторинга изменяется роль предварительного проектирования. Если не рассчитывать на рефакторинг, то ощущается необходимость как можно лучше провести предварительное проектирование. Возникает чувство, что любые изменения проекта в будущем, если они потребуются, окажутся слишком дорогостоящими. Поэтому в предварительное проектирование вкладывается больше времени и усилий — во избежание таких изменений впоследствии.
С применением рефакторинга акценты смещаются. Предварительное проектирование сохраняется, но теперь оно не имеет целью найти единственно правильное решение. Все, что от него требуется, — это найти приемлемое решение. По мере реализации решения, с углублением понимания задачи становится ясно, что наилучшее решение отличается от того, которое было принято первоначально. Но в этом нет ничего страшного, если в процессе участвует рефакторинг, потому что модификация не обходится слишком дорого.
Рефакторинг предоставляет другой подход к рискам модификации. Возможные изменения все равно надо пытаться предвидеть, как и рассматривать гибкие решения. Но вместо реализации этих гибких решений следует задаться вопросом: «Насколько сложно будет с помощью рефакторинга преобразовать обычное решение в гибкое?» Если, как чаще всего случается, ответ будет «весьма несложно», то надо просто реализовать обычное решение.
Рефакторинг позволяет создавать более простые проекты, не жертвуя гибкостью, благодаря чему процесс проектирования становится более легким и менее напряженным. Научившись в целом распознавать то, что легко поддается рефакторингу, о гибкости решений даже перестаешь задумываться. Появляется уверенность в возможности применения рефакторинга, когда это понадобится. Создаются самые простые решения, которые могут работать, а гибкие и сложные решения по большей части не потребуются.

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

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

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

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


Похожие записи:

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

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