рефакторинг программного кода это
Рефакторинг
Рефакторинг — это контролируемый процесс улучшения кода, без написания новой функциональности. Результат рефакторинга — это чистый код и простой дизайн.
Грязный код является не только результатом лени и невежества, но и побочным продуктом частых изменений в процессе разработки.
Чистый код — это код, который просто читать, понимать и поддерживать. Чистый код улучшает предсказуемость разработки и повышает качество продукта.
Пошаговые изменения, сопровождаемые частыми запусками тестов — это то, что делает процесс рефакторинга эффективным и безопасным.
Запахи кода — это индикаторы проблем, на которые нужно обращать внимание при рефакторинге. Часто их легко найти и исправить, но иногда они предвещают о глубинных проблемах с кодом.
Техники рефакторинга описывают конкретные методы борьбы с грязным кодом. Большинство рефакторингов имеет как достоинства, так и недостатки. Поэтому любой рефакторинг должен быть мотивирован и обдуман.
21 запах кода, 66 рефакторингов
Живые примеры на Java/C#/PHP
Никаких лимитов по времени
Руководство для инженеров по рефакторингу кода
В этом руководстве вы узнаете все о рефакторинге исходного кода: преимущества, проблемы, инструменты и методы, а также в чем разница между рефакторингом и техническим долгом.
В этом руководстве вы узнаете все о рефакторинге исходного кода: преимущества, проблемы, инструменты и методы, а также в чем разница между рефакторингом и техническим долгом.
Мы все ищем способы очистить наш код, упростить его и улучшить функциональность. Рефакторинг открывает путь вперед.
В этом руководстве будут рассмотрены следующие темы:
Что такое рефакторинг?
По словам Мартина Фаулера, автора двух книг по рефакторингу:
Рефакторинг — это процесс изменения программной системы таким образом, чтобы она, не изменяя внешнего поведения кода, стала лучше во внутренней структуре. Это способ очистки кода, сводящий к минимуму вероятность появления ошибок. По сути, когда вы проводите рефакторинг, вы улучшаете дизайн кода уже после того, как он был написан.
Каковы преимущества рефакторинга?
Рефакторинг исходного кода дает множество преимуществ. Он превращает беспорядочный, неправильный и/или повторяющийся код в чистый код. Он решает проблемы стандартизации, которые могут возникнуть, когда несколько разработчиков пишут свой собственный код. Рефакторинг обеспечивает лучшую читаемость и улучшает поддерживаемость исходного кода, а также его общую структуру и функциональность. Рефакторинг может упростить расширение кода и добавить новые функции. Удаление ненужных частей, таких как дубли, также может привести к тому, что код будет использовать меньше памяти и работать быстрее.
Например, в 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 Исходный код (также исходный текст) текст компьютерной программы на каком либо языке программирования или… … Википедия
Рефакторить или не рефакторить?
Мне нравится рефакторинг. Нет, не так. Я люблю рефакторинг. Не, даже не так. Я чертовски люблю рефакторинг.
Я не переношу плохой код и плохую архитектуру. Меня коробит, когда я пишу новую фичу, а в соседнем классе творится полный бардак. Я просто не могу смотреть на печально названные переменные. Иногда перед сном я закрываю глаза и представляю, что можно было бы улучшить в проекте. Иногда я просыпаюсь в три часа ночи и иду к ноутбуку, чтобы что-нибудь поправить. Мне хочется, чтобы на любой стадии разработки код был не просто кодом, а произведением искусства, на которое приятно смотреть, с которым приятно работать.
Если вы хоть немного разделяете мои ощущения, то нам есть о чём поговорить. Дело в том, что со временем что-то внутри меня начало подсказывать, что рефакторить всё подряд, везде и всё время — не самая лучшая идея. Поймите меня правильно, код должен быть хорошим (а лучше бы ему быть идеальным), но в условиях суровой реальности не всегда разумно постоянно заниматься улучшением кода. Я вывел для себя несколько правил о своевременности рефакторинга. Если у меня начинают чесаться руки что-нибудь улучшить, то я оглядываюсь на эти правила и начинаю думать: «А действительно ли сейчас тот момент, когда нужно нарефакторить?». Давайте порассуждаем о том, в каких же случаях рефакторинг уместен, а в каких — не очень.
Дисклеймер. Скорее всего, многим захочется после прочтения поста сразу сказать: «Да это уже 600 раз обсуждалось!» или «Это же настолько очевидно, зачем же об этом писать?». Возможно, вы и правы, но только вот какой момент: в окружающем мире по-прежнему творится хаос. Вроде бы всем всё понятно, но на деле получается, что не так уж и понятно. Поэтому я думаю, что не будет слишком вредно ещё разок взглянуть на эту тему. Но если конкретно у вас проблем с рефакторингом нет, то можете просто пропустить этот пост, у вас уже всё хорошо.
Слишком ранний рефакторинг
Нецелевой рефакторинг
Скорее всего, у вас есть план разработки на ближайшее время. Вполне вероятно, что у вас есть сроки (даже если вы их поставили сами). Релизы нужно делать вовремя, затягивать разработку не стоит. Нужно контролировать себя, нужно заниматься теми вещами, которые входят в ваши непосредственные цели. Допустим, у вас есть кусок кода, который выглядит как полное… Ну, в общем, плохо выглядит. Но, продолжим наше допущение, вы с ним сейчас не работаете. Этот плохой кусок кода стабильно работает, успешно справляется со своими задачами и никак не связан с вашей текущей задачей. Ну так и не трогайте его! Да, вас может крайне печалить то обстоятельство, что на другом конце проекта всё очень плохо. Но заметьте, что прямо сейчас вам это никак не мешает. У вас есть текущие задачи, занимайтесь ими. Конечно, бывают задачи по улучшению кодовой базы, но нечасто — зачастую важнее добавлять новый функционал или фиксить баги. Концентрируйтесь на текущих задачах и не бросайте их из-за того, что где-то там что-то как-то не так.
Рефакторинг ради рефакторинга
Ок, вы пришли к выводу, что нужно обязательно отрефакторить часть проекта. Хорошо, давайте отрефакторим. Вроде бы запланированные улучшения выполнены, но тут возникает мысль: «А что я могу ещё улучшить? Ага, вон ту штуку». А после вон той штуки появится вот эта штука, а потом ещё одна, а потом ещё и т. д. Нужно понимать, что есть плохой код, есть хороший код, есть идеальный код. Последнего в большом проекте у вас никогда не будет. Это не значит, что не нужно к нему стремиться, но нужно понимать его недостижимость. Обычно задача стоит в написании хорошего кода, а не идеального. Допустим, после рефакторинга у вас получился вполне читаемый код, который работает более или менее очевидным образом, в котором нет костылей и которым не так сложно пользоваться. Задайте себе вопрос: «А может, пора остановиться?». Да, код можно улучшать. Причём в достаточно большом проекте его можно улучшать до бесконечности. Но вот прямо сейчас он справляется со своими функциями, им удобно пользоваться, он практически не вызывает у вас дискомфорта. Очень важно определить для себя приемлемое качество кода, после которого вы перестанете его улучшать (до тех пор, пока свойство приемлемости не будет утрачено). Вспомните, что есть ещё так много разных клёвых штук, которые можно дописать. Не нужно рефакторить ради самого рефакторинга, ради идеального кода. Нужно рефакторить, когда у вас есть веские причины на это: код сложно прочитать, код сложно поддерживать, код сложно развивать, код сложно использовать и т. п. Если ни одного «сложно» не возникает, то веских причин тратить время на рефакторинг у вас нет.
Рефакторинг за день до релиза
Бывает так, что релиз послезавтра/завтра/сегодня/должен был быть вчера (нужное подчеркнуть). Это важный момент в жизни проекта. Нужно уделить особое внимание тестированию, фиксам критических багов, финальным доделкам. Поверьте, это действительно плохая идея — перерабатывать кодовую базу (а ещё хуже — качественно перерабатывать) в тот момент, когда нужно отдавать проект в продакшн. Опытная практика подсказывает, что нужно зарелизиться, а потом с чистой совестью спокойно улучшать код. Некоторые спросят: «А почему?». Если такой вопрос возник, то, наверное, вам ещё не приходилось делать сложный рефакторинг. Подскажу: при переписывании код не всегда обязательно улучшается — иногда он может сломаться. Да что там сложный рефакторинг — бывает, поправишь один метод на пять строк, не уследишь за какой-нибудь зависимостью, а на другом конце проекта выползет бага, с которой сразу же встретятся ваши любимые пользователи. Вот вроде бы ничего плохого и не делаешь, а тут внезапно на тебя нападает зверь «Это было неочевидно» и топит тебя в пруду ложной первоначальной оценки. Хотя, может, это просто я такой плохой программист — люблю что-нибудь сломать. Вполне возможно, что вы всегда рефакторите всё абсолютно правильно и с полным контролем всего проекта. В таком случае я могу вас поздравить, но от совета с запретом предрелизного рефакторинга всё-таки не откажусь. Поверьте, за несколько дней рефакторинг никуда не убежит, а сон у всей команды будет чуточку, но спокойней.
Рефакторинг очень старого кода
Вопрос тяжёлый, очень тяжёлый. Ситуация: есть огромное количество ужасных строк кода, которые достались вам от старых разработчиков (возможно, этими старыми разработчиками были вы несколько лет назад, ещё до того, как научились писать всё правильно и сразу). Код приходится поддерживать. То там, то тут возникают костыли и дублирования, энтропия растёт. С каждым днём всё больше хочется выкинуть всё и переписать с нуля. В такой момент нужно очень хорошо подумать о рисках. Да, вполне вероятно, что в перспективе такая деятельность будет полезна. Но в какой именно перспективе и насколько полезна? Скорее всего, в процессе большого рефакторинга или переписывания отдельных частей вы замените старый работающий говнокод новым, идеально написанным кодом, но с багами. И вовсе не из-за того, что вы плохой программист и пишете плохо. Просто вы можете не знать этот код в достаточной мере. Вы можете не знать, почему автор написал всё именно так, а ведь причины могли быть. Иногда приходится писать очень странный и кривой код. Я могу придумать очень много примеров: подавление хитрых оптимизаций процессора, подстройка под баги сторонней библиотеки, подавление каких-нибудь многопоточных косяков и т. д. Я не говорю, что нельзя все эти проблемы решить нормально. Просто иной раз при переписывании казалось бы абсурдного кода на нормальный появляются баги. Да, можно было всё сделать нормально, но вы можете просто не осознать всё величие шалаша из костылей вместо палок, если не узнаете у автора кода, почему он написал именно так (а подобная возможность предоставляется далеко не всегда). Будьте осторожны, когда переписываете старый код, который понимаете не до конца (а особенно, если думаете, что понимать там нечего).
А когда рефакторить-то?
Вместо заключения
Всё вышеперечисленное является чисто субъективным обобщением опыта работы над рядом проектов. Разумеется, я покрыл далеко не все жизненные ситуации. В каждой команде свои требования к коду, свой бизнес-план и свои правила. Уверен, что у многих найдётся пяток историй из серии «А вот у меня был случай, когда все эти советы не работают». Это абсолютно нормально, так и должно быть. Нет универсальной серебряной пули для определения количества усилий на улучшение кода («Мы будем каждый день 47 минут 23 секунды заниматься рефакторингом — и всё у нас будет хорошо»). Вам нужно исходя из собственного опыта в вашем конкретном проекте, в вашей конкретной команде попытаться найти золотую середину между написанием нового кода и улучшением старого. Я агитирую только за то, чтобы ко всему было рациональное отношение без фанатизма («Зачем улучшать код, нового функционала от этого не появится» / «Нужно срочно весь код сделать идеальным, чтобы потом с ним можно было нормально работать»). Подходите разумно к распределению времени на работу над существующим кодом — и всё у вас будет хорошо.
Приветствуются любые дополнительные мысли о том, когда стоит или не стоит рефакторить. Одна из наиболее ценных вещей в этой области — опыт реальных разработчиков над реальными проектами.