Рефакторинг что это

Рефакторинг что это

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

Как сделать код чище и понятнее.

В среде разработчиков можно услышать: «Мне нужен год на рефакторинг» (полгода, месяц, неделя, хотя бы денёк). Что это значит и зачем это нужно — разберём.

На примере кафе

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

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

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

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

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

Когда нужен рефакторинг в программировании

Есть два подхода к рефакторингу: плановый и по необходимости.

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

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

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

На что смотрят при рефакторинге кода

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

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

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

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

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

А можно без рефакторинга?

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

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

Что дальше

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

Источник

Что такое рефакторинг кода? Основные принципы и правила рефакторинга

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

Так в чем проблема? Только в том, что с рефакторингом связан известный риск. Он требует внести изменения в работающий код, что может привести к появлению трудно находимых ошибок в программе. Неправильно осуществляя рефакторинг, можно потерять дни и даже недели. Еще большим риском чреват рефакторинг, осуществляемый без формальностей или эпизодически. Вы начинаете копаться в коде. Вскоре обнаруживаются новые возможности модификации, и вы начинаете копать глубже. Чем больше вы копаете, тем больше вскрывается нового и тем больше изменений вы производите. В конце концов, получится яма, из которой вы не сможете выбраться. Чтобы не рыть самому себе могилу, следует производить рефакторинг на систематической основе. В книге «Design Patterns» сообщается, что проектные модели создают целевые объекты для рефакторинга. Однако указать цель — лишь одна часть задачи; преобразовать код так, чтобы достичь этой цели, — другая проблема.

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

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

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

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

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

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

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

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

Принципы рефакторинга

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

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

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

Когда следует проводить рефакторинг?

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

Почему рефакторинг приносит результаты

Из-за чего бывает трудно работать с программами? В данный момент мне приходят в голову четыре причины:

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

Когда рефакторинг не нужен?

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

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

Другой случай, когда следует воздерживаться от рефакторинга, это близость даты завершения проекта. Рост производительности, достигаемый благодаря рефакторингу, проявит себя слишком поздно — после истечения срока. Правильна в этом смысле точка зрения Уорда Каннингема (Ward Cunningham). Незавершенный рефакторинг он сравнивает с залезанием в долги. Большинству компаний для нормальной работы нужны кредиты. Однако вместе с долгами появляются и проценты, то есть дополнительная стоимость обслуживания и расширения, обусловленная чрезмерной сложностью кода. Выплату каких-то процентов можно вытерпеть, но если платежи слишком велики, вы разоритесь. Важно управлять своими долгами, выплачивая их часть посредством рефакторинга.

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

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

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

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

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

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

С производительностью связано то интересное обстоятельство, что при анализе большинства программ обнаруживается, что большая часть времени расходуется небольшой частью кода. Если в равной мере оптимизировать весь код, то окажется, что 90% оптимизации произведено впустую, потому что оптимизировался код, который выполняется не слишком часто. Время, ушедшее на ускорение программы, и время, потерянное из-за ее непонятности — все это израсходовано напрасно.

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

Разработка тестов

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

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

Источник

Рефакторинг — мощь сокрытая в качественном коде

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

Проектирование

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

Начать проектировать можно очень легко. Всегда держите на рабочем месте блокнот и несколько цветов ручек. Прежде чем писать код, нарисуйте схему — как приложение будет работать в целом, UML-диаграмму классов (продумайте как можно с минимальным количеством классов, достигнуть максимального результата), структуру баз данных (оптимизируйте БД еще до ее создания, подумайте какие запросы у вас должны будут «бегать» к вашей БД, продумайте индексы, конечно же нормализируйте вашу модель данных).

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

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

Несколько принципов, которые точно нужно знать при проектировании классов вашей «Feature»:

1. SOLID (single responsibility, open-closed, Liskov substitution, interface segregation и dependency inversion)

Это основа основ в проектировании классов. Если вы еще не знакомы с SOLID, здесь можно ознакомиться.

2. DRY (do not repeat yourself)

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

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

— Вместо использования функции progress50(), лучше применить более абстрактную progress($percent).

— Отдавать предпочтение внешним зависимостям между модулями, внутренним (DI), что делает модуль более гибким и позволяет его использовать в нескольких местах.

3. KISS (keep it simple, stup. )

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

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

Стиль кода

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

Стандарт стиля кода (и не только) PSR (PHP Standards Recommendations), здесь можно ознакомиться. Содержимое на английском языке, так как английский более ясно дает понять степень применения одного или другого правила («MUST», «MUST NOT», «REQUIRED», «SHALL», «SHALL NOT», «SHOULD», «SHOULD NOT», «RECOMMENDED», «MAY», and «OPTIONAL»).

Несколько замечаний, которые автор счел важными:

1. Ознакомьтесь с PHPDOC для написания комментариев к вашему коду.

2. Лучший комментарий — это правильно названный класс, метод, параметр или переменная.

3. Используйте утилиты PHPMD, PHPCS, их применение шире, чем только для определения несоответствий в стиле кода. Вот документация: PHPMD, PHPCS.

4. Используйте продвинутое IDE.

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

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

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

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

1. Длинные методы (лучше разделить функционал на несколько методов).

2. Громоздкие классы (ваш класс должен исполнять одну функциональную задачу в вашей системе).

3. Неясная структура класса (методы в хаотическом порядке, конструктор в середине класса, вместо констант — магические значения в коде — класс должен легко отображать, что он делает в правильной последовательности).

4. Слишком много параметров в методе (некоторые расчеты можно сделать внутри метода, используя внутренние константы, значения полученные с атрибутов и геттеров).

5. Классы, содержащие одинаковые переменные и методы. Проблему можно решить через создание дополнительного класса).

6. Сложно читаемый IF (выражение можно вынести в отдельную переменную и разделить на логические части, которые также вынести в переменные, если много проверок на null, то лучше всего использовать NullObject — количество проверок значительно уменьшится).

7. Громоздкий SWITH (выносим в отдельный метод).

8. Использование наследования из-за одинаковых методов и свойств, в разных по своей сути сущностях (кошка и стул имеют ноги, но их нельзя группировать в категорию «животные»).

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

10. Слишком сложный функционал в одном классе, который можно разделить на несколько классов.

11. Класс делает слишком мало, чтобы его оставлять в системе.

12. «Мертвый код» — его следует удалить.

13. Не использованные структуры классов, которые вы проектировали на будущее, но они так и не пригодились — такие лучше удалить.

14. Методы класса больше используются в другом классе, а в своем вообще не используются или же реже (стоит перенести метод в тот класс, где он больше используется).

15. Слишком длинная цепочка вызовов ($a->b()->c()->d()->e()), в этом случае стоит создать дополнительные методы.

16. Класс, содержащий только один метод, который создает другой класс. (Такой класс нужно использовать с умом, к примеру, для паттерна «Прокси», в противном случае этот класс только увеличивает время и ресурс на поддержку проекта).

Источник

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

Рефакторинг что это

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

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

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

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

Рефакторинг что это

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

Определение Мартина Фаулера

Вопрос «Что такое рефакторинг?» часто возникает у программистов-новичков, а иногда и у более опытных разработчиков. Поэтому он регулярно всплывает на форумах в духе StackOverflow.

Там в качестве ответа на вопрос приводят цитату из книги «Refactoring: Improving the Design of Existing Code» за авторством Мартина Фаулера:

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

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

Что не является рефакторингом?

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

простое переписывание кода,

улучшения функциональной составляющей ПО,

Первое имеет смысл при создании нового ПО или самотренировок.

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

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

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

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

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

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

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

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

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

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

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

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

В каких случаях нужен рефакторинг?

Есть ряд ситуаций, которые «кричат» о необходимости рефакторинга:

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

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

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

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

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

На какие аспекты кода направлен рефакторинг?

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

Неиспользуемый код

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

Дубликаты

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

Переменные и функции названы неадекватно

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

Рефакторинг что это

Код, из которого невозможно что-либо понять

Избыточное количества текста в одном методе

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

Рефакторинг что это

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

Та же функция, но описанная одной строкой

Избыточное количество комментариев

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

Некорректно оформленные куски кода

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

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

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

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

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

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

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

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

Опытные разработчики рекомендуют следующие практики:

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

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

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

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

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

Обучиться рефакторингу можно на курсах по программированию общего назначения у EPAM и Hexlet, а также на узкоспециализированных ресурсах в духе Refactoring Guru.

Источник

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

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

Рефакторинг что это

Рефакторинг что это

Рефакторинг что это

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Модульное, иногда блочное или юнит-тестирование (англ. unit testing) — процесс в программировании, позволяющий проверить на корректность отдельные модули исходного кода программы.

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

Интеграцио́нное тести́рование — одна из фаз тестирования программного обеспечения, при которой отдельные программные модули объединяются и тестируются в группе.

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

Источник

Цена рефакторинга

Рефакторинг что это

Вдохновители

Писать начал после очередного просмотра пулл-реквеста на 150+ файлов, где было люто замешана новая функциональность и рефакторинг существующей. Рефакторинг был не только косметическим, но и логическим, который вызывал наибольшую боль. Например, в Ruby amount == 0 смело заменялся на amount.zero? без учёта того, что для случая nil в amount эти конструкции не эквивалентны. Объяснялось же всё это примерно так: «но по код стандарту так положено!» На логичный вопрос «какая цель следования код стандарту и вообще, какая цель у тебя как разработчика?» человек замыкался в себе и немного виновато повторял «но по код-стандарту же вот так писать надо. » и выглядел как блондинка в магазине одежды, которая не в силах совладать с желанием отрефакторить купить всё.

Определение

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

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

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

Ценность продукта

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

Прямые ценности продукта

Тут всё просто. Продуктом пользуются, поэтому прямые ценности это то, что явно щупает/видит/чувствует пользователь. А именно:

Второй пункт может вызвать некоторую дискуссию. Ведь многие считают, что это не главное. Так как если функциональность хороша, то не важно во что она завёрнута. Хорошие примеры функциональности без вменяемого UI/UX: Redmine и SAP. Однако я с таким взглядом не согласен и ближе по взглядам к товарищу Алану Куперу и его «Психбольнице в руках пациентов».

Косвенные ценности продукта

Это те ценности, которые сами по себе на пользователя не влияют. Но могут «выстрелить» или «накопиться» и оказать влияние (разной степени тяжести) на продукт или его функциональность.

Ценности для разработчика

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

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

Взгляд со стороны бизнеса

Для полноты картины надо бы посмотреть на всё это со стороны бизнеса, а не программного продукта. В этом случае, разделение на прямые и косвенные ценности становится довольно банальным: прямые — явно приносят деньги и можно дать однозначную количественную оценку; косвенные — денег не приносят и/или количественную оценку дать очень сложно; ценности для разработчика денег не приносят ни в каком виде (возможно, даже отнимают их).

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

Справедливости ради, тут нужно вспомнить понятие enabler’а, который «открывает дорогу» к реализации желаемой фичи, но явного профита пользователю не несёт. Но это уже другая история.

Причём тут рефакторинг?

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

Так же, важно помнить про энтропию. Рефакторинг всегда неуменьшает её. Для уменьшения энтропии, в идеале, нужна команда архитекторов, минимизирующих энтропию на этапе проектирования. Процитирую кусочек из Мифического человекомесяца:

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

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

Какие цели могут быть у рефакторинга?

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

За энтропию!

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

За документацию!

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

За быстродействие!

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

В эту категорию входит всё: от безобидного исправления N+1 до серьёзного ускорения за счёт изменения алгоритмов работы. Вся проблема в том, что на скорости всегда сидит «чётность» багов. Вот, к случаю, пример из жизни: внутри одной транзакции пушатся данные в БД и в этой же транзакции ставится задача в Sidekiq; очередь Sidekiq’а в Redis’е и транзакция на него не распространяется; при увеличении скорости работы очереди таска иногда берётся на выполнение раньше, чем закоммитятся данные; последствия и процесс дебага можете представить сами.

За рефакторинг!

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

Надеюсь, вы поняли, что думать нужно не о себе, а о том, для кого вы это делаете.

Смирение и принятие

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

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

Конец

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

Источник

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

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

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

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

Для разработчиков переписывать раз за разом и свои, и чужие коды – привычное дело. Ничего нового в код не добавляется, не исправляется. Но для чего тогда это нужно?

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

Рефакторинг что этоЧто такое рефакторинг программного кода

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

На форумах вроде StackOverflow вопрос о том «Что такое рефакторинг?» обсуждается довольно часто. И это неудивительно, потому что его задают не только новички, но и разработчики со стажем.

На подобных форумах для объяснения понятия рефакторинг кода обращаются к книге Мартина Фаулера «Refactoring: Improving the Design of Existing Code». Определение тут приводится такое (цитата):

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

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

Источник

Руководство для инженеров по рефакторингу кода

В этом руководстве вы узнаете все о рефакторинге исходного кода: преимущества, проблемы, инструменты и методы, а также в чем разница между рефакторингом и техническим долгом.

Рефакторинг что это

В этом руководстве вы узнаете все о рефакторинге исходного кода: преимущества, проблемы, инструменты и методы, а также в чем разница между рефакторингом и техническим долгом.

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

В этом руководстве будут рассмотрены следующие темы:

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

По словам Мартина Фаулера, автора двух книг по рефакторингу:

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

Каковы преимущества рефакторинга?

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

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

Технический долг vs рефакторинг

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

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

Рефакторинг что это

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

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

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

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

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

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

Красный, зеленый, рефакторинг

Рефакторинг идет рука об руку с модульным тестированием. Одна из наиболее распространенных форм — разработка через тестирование (TDD), присущая методологии Agile. Вы пишете тесты перед написанием кода. По сути, тесты должны управлять программой, указывая, что должен делать код.

Красный, зеленый, рефакторинг — это пример TDD:

Метод извлечения (также известный как функция извлечения)

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

Извлечение переменной

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

Ветвь по абстракции

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

Составной метод

Чрезмерно длинный код трудно понять и изменить. Метод Compose относится к ряду действий, которые можно использовать для оптимизации методов и устранения дублирования кода. К ним относятся Inline Method, Inline Temp, Replace Temp with Query, разделение временных переменных и удаление назначений параметрам.

Инструменты рефакторинга кода

Вам нужны специальные инструменты для рефакторинга? Мартин Фаулер говорит, что автоматизированные инструменты полезны, но не важны. Он отмечает:

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

Многие среды разработки автоматизируют механические аспекты рефакторинга. Инструменты рефакторинга ключевого кода:

Рефакторинг и вызовы для инженеров

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

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

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

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

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

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

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

Командная поддержка и рефакторинг: спринт или марафон?

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

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

Однако он подчеркивает, что исправление плохого кода требует много времени, и придерживается более продуманного подхода, чем простое погружение в изменения:

“Мы улучшаем код, в котором работаем, и игнорируем код, с которым нам не нужно работать. Скорее всего, мы еще вернемся к нему.

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

Инженер по продукту и технический директор Андреас Клингер — поклонник Fix-it Friday.

Правило Fix-it Friday простое: если ваш текущий проект не горит, используйте пятницу, чтобы инвестировать в небольшие улучшения. Позвольте инженерам выбирать, над чем они работают. Постарайтесь не лишать «удовольствия» такой их микроменеджмент. Некоторые попробуют новые библиотеки. Некоторые удаляют ошибки из бэклога. Оба подхода нормальные. Постарайтесь добиться баланса в задачах.

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

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

Документация и рефакторинг

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

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

Кроме того, задокументируйте свои успехи — каковы были самые большие выгоды от рефакторинга? Могут ли они быть учтены в экспертных обзорах?

Утопаете в коде, который требует рефакторинга и технического долга?

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

Источник

Рефакторинг

Содержание

Цели рефакторинга

Цель рефакторинга — сделать код программы легче для понимания; без этого рефакторинг нельзя считать успешным.

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

Причины применения рефакторинга

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

Признаки плохого кода

Во многом при рефакторинге лучше полагаться на интуицию, основанную на опыте. Тем не менее имеются некоторые видимые проблемы в коде (англ. 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 Исходный код (также исходный текст) текст компьютерной программы на каком либо языке программирования или… … Википедия

Источник

Приключение на 20 минут: о чём надо помнить, когда затеваешь рефакторинг

Рефакторинг что это

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

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

Бац-бац — и в продакшен?

«Что ж, эта задачка не займёт много времени, — наивно думал я. — Просто обновляем TargetFramework для всех проектов, обновляем nuget и смело возвращаемся к бизнесовым таскам».

Проблемы начались сразу же.

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

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

Я вот думаю, что сила в тестах. У кого тесты — тот и сильней

Тесты мы гоняем на выполняющейся в памяти базе данных EF Core (они очень быстрые, хотя их основным недостатком является то, что это всё-таки не настоящая база данных). После исследования причин мы поняли, что дело в баге внутри библиотеки EF Core 6 (появился ещё в пятой версии и планируется к починке только в седьмой). Он заключается в том, что при использовании строго типизированных первичных ключей (например, если в качестве айдишника используется класс) перестаёт правильно работать механизм JOIN’ов.

Для управления базами данных в проекте мы используем MySQL. Все первичные ключи в таблицах — это UUID (подробнее о работе MySQL с GUID/UUID можно почитать здесь). В коде UUID представлены классом, что и приводит к проблеме.

Как маленькая структура большому проекту помогла

С этого поиска мы и начали. У нас есть несколько своих библиотек, одна из них — публично доступный nuget Dodo.Primitives.Uuid, из которого родился небольшой фикс рантайма. Библиотека подойдёт всем, кто хочет использовать в своём приложении GUID-like первичные ключи, но по тем или иным причинам до сих пор стесняется.

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

Рефакторинг что этоПорядок в байтах отражает порядок в мыслях

Меня она заинтересовала в первую очередь тем, что вместо класса объект UUID представлен в ней структурой и в теории это могло помочь победить баг.

Проводим эксперимент в лабораторных условиях

Итак, мы нашли библиотеку, которая может решить нашу проблему. Что ж, начинаем заменять старые UUID на новые? Нет! Сначала нужно проверить гипотезу.

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

Проверить гипотезу лучше всего можно на простом консольном приложении — такой подход позволит исключить влияние других элементов системы. Для полной уверенности необходимо воссоздать весь предстоящий процесс обновления. Для этого подключаем библиотеки, которые позволят сымитировать текущую версию приложения (.NET Core 3.1 + EF Core 3.1.21 и нашу внутреннюю библиотеку, отвечающую за UUID) и напишем запрос в базу данных, который, как мы считаем, должен сломаться после обновления:

Рефакторинг что это

Короткий период ликования сменяется нелёгкими мыслями о том, что необходимо заменить все UUId в приложении на новые, причём они не полностью совместимы. Напомню, что старые были классами, а новые — структурами. Что же их отличает? Отметаем в сторону наследование (иерархическую структуру первичных ключей в проекте мы пока не завели), остаётся то, что структуры не могут быть null, а вот классы ещё как могут. Это означает, что нам придётся разрулить в коде кучу случаев, где мы обNULLяем наши айдишники.

С новыми силами приступаем к рефакторингу

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

Всегда стоит помнить, что изменения должны быть контролируемыми, особенно если мы меняем логику приложения. Чем дольше наша программа находится в «разобранном» виде, тем больше шанс запутаться и облажаться на рефакторинге. Мы логику менять не собираемся, а значит (учитывая необходимое количество изменений) можно сделать рефакторинг более «ковровым» методом — меняем всё поиском и заменой текста.

Поэтому подключаем Dodo.Primitives.Uuid и соответственно заменяем using Dodo.Tools.Types (старая библиотека) на using Dodo.Primitives во всём решении, UUId на Uuid и правим другие такие же мелочи (например, старый UUId создавался как NewUUId, а новый — NewMySqlOptimized). По мере исправления сначала будет много ошибок, но после всех шагов их станет куда меньше. Остались только те случаи, которые нам придётся разрулить руками:

Рефакторинг что это

В такой ситуации мы всегда можем сделать Nullable Uuid, однако не стоит подходить к этому опрометчиво. Такое изменение очень быстро начинает «всплывать» и может привести к ситуации, когда все Uuid в приложении обрастают знаками вопроса. База данных — лучший источник истины в такой ситуации.

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

Без регресса нет прогресса

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

Есть ли жизнь после рефакторинга?

Скорее всего, что-нибудь сломается. Мы сделали всё что могли, и если мы были умны и внимательны, если не потеряли мотивацию и не поленились, то с красными лицами к нам придёт совсем мало разработчиков, а проблемы удастся очень быстро поправить. Я считаю, что это отличная возможность выявить самые уязвимые и не покрытые тестами места в приложении и исправить.

Знаете, я многое узнал сегодня.

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

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

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

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

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

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

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

Основной идеей статьи было не только лишний раз уберечь вас от избыточной самоуверенности, но и показать несколько довольно простых и эффективных приёмов рефакторинга, которые помогут найти подход к, казалось бы, большой проблеме. Если решать задачу постепенно и с умом, то нет ничего невозможного. Можно провернуть любую смелую идею, обойти или исправить страшный баг, провести успешный эксперимент, который убедит команду, что ваше решение — самое-самое.

Источник

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Источник

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

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

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

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

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

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

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

Рефакторинг что это

Когда надо выполнять рефакторинг

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

Замусориватели

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

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

Раздувальщики

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

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

Нарушители ООП

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

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

Утяжелители изменений

Сюда входят проблемы, из-за которых невозможно изменить один участок кода, не внося при этом корректировки в других его местах, а именно:

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

Другие признаки

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

Эти проблемы возникают в случае, когда разработчик неправильно оперирует связями в ООП.

Рефакторинг что это

Эффективные методы рефакторинга

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

Составление методов

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

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

Организация данных

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

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

Упрощение условий

Одна из задач рефакторинга – минимизировать количество условных операторов в коде. Варианты:

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

Рефакторинг что это

Что еще рефакторить

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

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

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

Источник

UX Рефакторинг. Что это такое и чем отличается от редизайна

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

Мартин Фаулер в книге “Рефакторинг” дал определение:

“Рефакторинг представляет собой процесс такого изменения программной системы, при котором не меняется внешнее поведение кода, но улучшается его внутренняя структура”

Применительно к UX и интерфейсам — тут всё внешнее. Так что основной вопрос — определения того синонима “внешнее поведение кода”, которое будет ложиться на изменение структуры интерфейса.

Считая, что “внешняя работа кода” — это результат выполнения кода, результатом работы с интерфейсом будет достижение целей пользователя. Синонимом “внутренней структуры кода” будет сам интерфейс и логика работы с ним (UX).

Перефразируя Фаулера, “ UX рефакторинг представляет собой процесс такого изменения интерфейса, при котором не меняются цели пользователя, но меняется сам интерфейс и логика работы с ним (UX)”. Давайте теперь рассмотрим вопрос более формально.

Термины и определения

Любой интерфейс можно рассматривать с той точки зрения, что пользователь хочет достичь своих целей, совершить “главное действие в интерфейсе”. А для этого на каждом шаге надо понимать какой результат он получит, делая то или иное действие. И чем понятнее этот результат на каждом этапе, тем интерфейс требует меньше усилий по достижению целей.

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

В общем случае и количество нажатий кнопок, и само время работы с интерфейсом — это СЛЕДСТВИЯ из эффективности интерфейса. Пользователю недостаточно информации для принятия решения куда нажать и что будет после этого.

Если посмотреть еще более глубоко, то время работы с интерфейсом (time to task) также зависит от количества нажатий. Пользователь не понимает что надо сделать, совершает избыточные действия, ошибки, затем их исправляет и так до тех пор, пока не достигнет успеха.

Определим следующие термины:

“Недостаток” интерфейса — это те моменты, где пользователю недостаточно информации для принятия решения что делать.

Более общее утверждение: если у пользователя есть несколько вариантов действия, то это недостаток первого типа.

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

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

Рефакторинг что это

“Каждый раз, когда вы просите пользователя сделать выбор — заставляете принимать решение. Это не всегда плохо. Но точно плохо, если выбор не относится к задаче, которую решает человек. Лучше сделать выбор за пользователя везде, кроме его основной задачи”

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

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

“Дефект” интерфейса — это тупиковые ветки пути

Рефакторинг что это

В частности, заблокированные (disable) кнопки — это индикаторы тупиковых ветвей, которые указывают на дефекты. Сообщения об ошибках, которые получает пользователь в интерфейсе — это дефекты. Тупик, куда он попал, делая что-то не так, как задумывали проектировщики интерфейса.

Рефакторинг что это

Путь пользователя — это дерево решений, где на каждом этапе пользователь должен понять что надо сделать, чтобы достичь своей цели. Да, это очень похоже на CJM (Customer Journey Map) с его барьерами.

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

Рефакторинг что это

Используя введенные термины, можно более формально определить UX рефакторинг:

“UX рефакторинг” — это устранение дефектов и недостатков интерфейса, без изменения остальной логики.

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

Примеры

Давайте на конкретных примерах разберем где недостатки, а где дефекты.

Пример 1. Форма подписки

Рефакторинг что это

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

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

Недостатком на картинке является активная кнопка “Подписать”. Если пользователь нажмет на неё, не введя адрес, то он получит дефект — сообщение об ошибке. Как минимум, ее стоит сделать неактивной. Идеально — убрать вообще, чтобы даже неактивная кнопка не была индикатором тупикового действия и не смущала пользователя.

Рефакторинг что это

Если же по шагам посмотреть как пользователь вводит адрес, то можно сделать подсказки, что ожидается символ ввода @, а затем точка.

Пример рефакторинга дефектов и недостатков этой формы приведен в статье “UX рефакторинг на примере формы подписки”

Рефакторинг что это

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

А если делать рефакторинг не отдельной формы, а всего сайта, то единожды введенный email на сайте (при регистрации, в форме обратного звонка, при оформлении доставки, при подписке) — автоматически должен подставиться во всех местах сайта, где предполагается ввод электронной почты пользователя. Один раз ввели — используем везде.

Пример 2. Сообщение в Word

Рефакторинг что это

Что мешает, например, сохранять файл в Word автоматически? При закрытии останется выбор между двумя кнопками — “Не сохранять” / “Отмена”. Тем более, что он уже где-то сохранен, раз будет “временно доступен”. Кнопка “Сохранить” нужна только для того, чтоб задать корректный путь к папке, где будет храниться файл.

Кнопка “Отмена” фактически означает действие “Продолжить редактирование”. Чем “Отмена” отличается от “Не сохранять” из сообщения об ошибке не очевидно. Это недостаток первого типа.

Хорошо и плохо

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

Что же такое идеальный интерфейс? К чему стоит стремиться при рефакторинге? Как минимум, есть несколько следствий того, что интерфейс идеален или близок к нему:

Идеальный интерфейс вообще не содержит дефектов и недостатков.

Для устранения дефектов и недостатков в интерфейсе надо показать пользователю что случится в случае того или иного действия. Куда он попадет, в какое состояние? Что сделает конструкция, что изменится. Для этого надо вытащить признаки цели (со следующего или дальнейших шагов) на этап текущего шага. Более подробно про эту концепцию описано в статье “Признаки и свойства”.

Измеримость результатов

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

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

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

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

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

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

Если вам понравилась статья — не стесняйтесь апплодировать!

Отдельное спасибо Wova Roodnyy за идеи, методику и консультации.

Источник

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

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