Рефакторинг или переписывание кода?
Разработка программного обеспечения - область, в которой не обходится без споров. Но если бы нам пришлось выбирать наиболее острый из них, то это был бы спор на тему "рефактор или рерайт". Как показывает беглый поиск в Google, существует столько же мнений, сколько разработчиков программного обеспечения, поэтому прийти к единому мнению - это что-то близкое к утопии.
Тем не менее, команды разработчиков программного обеспечения чаще всего оказываются перед таким выбором, поэтому нередко люди обращаются к этим мнениям в поисках помощи. Однако, учитывая разнообразие точек зрения, это становится похоже на прыжок веры.
Мы не можем дать однозначного ответа, потому что его нет. Как и многое другое в разработке программного обеспечения, все зависит от нескольких факторов, специфичных для каждой конкретной ситуации. Другими словами, не существует общих правил относительно того, что лучше - рефакторинг или переписывание кода, - даже если многие эксперты или опытные разработчики утверждают, что лучше поступить именно так, а не иначе.
На наш взгляд, лучше развивать критическое мышление, чтобы подходить к любому проекту, который может быть подвергнут рефакторингу или рерайтингу. Вооружившись им, вы сможете оценить любой сценарий, который попадется вам на глаза, и определить, как лучше поступить. Читайте далее, чтобы узнать, о чем нужно помнить. Но сначала давайте убедимся, что мы находимся на одной волне.
Критерии
|
Рефакторинг кода | Переписать код |
Основная роль | Улучшение дизайна существующего кода без изменения его внешнего поведения | Заменить существующий код новой версией, обеспечивающей ту же функциональность |
Основные задачи | Очистка кода, оптимизация, удаление избыточности, улучшение читабельности | Начало работы с нуля, проектирование, кодирование и тестирование |
Необходимые навыки
|
Понимание кодовой базы, хорошее знание языка программирования, техники рефакторинга | Уверенное знание языка программирования, принципов проектирования программного обеспечения |
Потребление времени | Обычно менее трудоемко, выполняется инкрементально | Более трудоемко, приходится переписывать всю кодовую базу. |
Риск | Низкий риск, поскольку изменения небольшие и инкрементные | Более высокий риск, так как в новом коде могут появиться новые ошибки |
Стоимость | Как правило, ниже, поскольку не требует полного переписывания кода | Более высокая, так как требует полной переделки. |
Существующие ошибки
|
Может помочь выявить и устранить некоторые существующие ошибки | Существующие ошибки могут быть устранены, но могут появиться новые |
Понимание кода | Повышает понимание кодовой базы разработчиками | Может улучшить или ухудшить понимание, в зависимости от сложности кода |
Влияние на функциональность | Не добавляет новых функций, а фокусируется на улучшении существующего кода | Может добавлять новые возможности и улучшения наряду с переписыванием существующего кода |
Тестирование
|
Требуется тестирование, но, как правило, менее масштабное из-за небольших, инкрементных изменений | Требуется тщательное тестирование всех функциональных возможностей |
Лучше всего подходит для | Кодовые базы, нуждающиеся в незначительных улучшениях или имеющие проблемы с сопровождением | Кодовые базы, которые трудно поддерживать, понимать или которые плохо структурированы. |
Результат | Повышение качества кода, улучшение сопровождаемости, потенциально более высокая производительность | Новая кодовая база, потенциально с улучшенной структурой, производительностью и новыми возможностями |
Одна из наиболее часто встречающихся проблем в статьях, посвященных этой дискуссии, заключается в том, что их авторы обычно не уточняют, что они имеют в виду под рефактором и рерайтом. Возможно, это происходит потому, что они считают, что разработчики знают, о чем говорят. Возможно, это и так (любой разработчик знает об этих практиках, независимо от своего опыта), но дело в том, что универсального определения для них не существует.
Поэтому, чтобы избежать путаницы, я расскажу вам, что мы думаем о них. Оно может отличаться от вашего определения, и это нормально. Мы не пытаемся убедить вас в необходимости использования этих определений. В основном это делается для того, чтобы прояснить, о чем я буду говорить, когда буду ссылаться на оба определения в дальнейшем.
Когда речь заходит о рефакторинге, мы больше придерживаемся школы Мартина Фаулера. Это означает, что всякий раз, когда мы говорим о рефакторинге, мы имеем в виду изменение дизайна чего-либо без влияния на его поведение. Речь идет о ретушировании кода с целью повышения его качества, в то время как программное обеспечение остается прежним. Таким образом, результат выглядит так же, но обладает лучшей производительностью, безопасностью, лучше интегрируется с новыми технологиями, лучше масштабируется и т.д.
С другой стороны, переписывание - это удаление всего существующего кода и начало работы с нуля, чтобы прийти к тому же (или даже лучшему) результату. Это означает понимание программного обеспечения в его нынешнем виде и воссоздание его с помощью нового кода. Можно сказать, что это "ядерный вариант", поскольку вы избавляетесь от того, что у вас есть, чтобы предложить лучшую альтернативу.
Вообще, разработчики любят переписывать. На это есть несколько причин: проще начать с нуля, не нужно беспокоиться о том, что что-то сломается из-за того, что вы подправляете отдельные куски кода, можно создать более качественный продукт - можно даже написать для него лучшую документацию, пока вы его переписываете! Однако считать, что переписывание лучше именно из-за этих вещей, значит добровольно игнорировать другие важные аспекты, которые изначально связаны с решением о переписывании.
Давайте рассмотрим некоторые из них.
За пределами переписывания "Песни сирены"
Все перечисленные выше причины - это первое, что приходит в голову инженерам-программистам, когда они сталкиваются с неработающим, старым программным продуктом. Все заканчивается одинаково - инженеры хотят переписать программу, чтобы начать с чистого листа. Однако разработчики редко являются единственными решателями судьбы программного обеспечения. На самом деле, некоторые соображения часто оказываются более значимыми при принятии решения.
Среди них на первом месте стоят бизнес-факторы. Переписывание (особенно сложных программ) может занять много времени и в итоге обойтись в кругленькую сумму, не принося реальной пользы с точки зрения бизнеса. Возможно, на переписывание программного обеспечения тратится слишком много ресурсов, что мешает команде сосредоточиться на более важных задачах. Возможно, переписанное программное обеспечение не имеет достаточного ROI, чтобы оправдать переписывание. Таким образом, переписывание часто противоречит целям бизнеса, что является основной причиной отказа от него.
Это приводит нас к сопутствующим рискам, связанным с переписыванием. Возможно, переписывание всего программного обеспечения может дать эффект для бизнеса, но за то время, которое потребуется для завершения работы, оно позволит конкурентам быстрее выпустить на рынок аналогичный продукт. Возможно, после завершения переписывания на рынке появятся новые конкуренты. А может быть, деньги, вложенные в рерайт, не позволят вам инвестировать в более стратегический актив (технологический или нет).
Наконец, есть некоторые аспекты, связанные непосредственно с самим программным обеспечением. Возможно, программное обеспечение, которое вы хотите переписать, не так просто поддерживать, но оно устойчиво к внешним воздействиям, обеспечивает высокую степень безопасности и имеет отличную производительность. Если вы не уверены, что сможете повторить все это, переписывание может закончиться неудачей. В итоге вы можете получить более удобное для сопровождения программное обеспечение, которое не будет столь же устойчивым, безопасным или будет работать хуже, чем то, что было раньше.
Приведение этих соображений не означает, что переписывание - это плохой вариант. Напротив, они предоставляют необходимую информацию, которую следует учитывать при принятии решения. Таким образом, они помогают нарисовать более реалистичную картину того, что может означать переписывание.
Разработка критического подхода
Поскольку переписывание - это то, что рассматривается большинством разработчиков программного обеспечения при необходимости улучшения существующей системы, то начинать нужно именно с него. Рассмотрение бизнес-причин и связанных с ними рисков может стать отличным способом решить, подходит ли вам переписывание. Проще говоря, прежде чем рассматривать технические аспекты, необходимо определить, является ли переработка для вас приемлемым вариантом.
Однако в этом вопросе есть одна сложность. Возможно, вы рассматриваете возможность переписывания или рефакторинга потому, что у вас слишком большой технический долг или ваше программное обеспечение близко к устареванию. В таком случае оба варианта рискованны. Если вы оставите все как есть, просто потому что все работает, вы рискуете тем, что ваше программное обеспечение не продержится долго, его невозможно будет поддерживать в ближайшем будущем или оно не будет масштабируемым. Если переписать его, то можно не получить тех же возможностей.
Это означает, что не существует варианта без риска - учитывайте его и знайте о нем, но не основывайте свое решение только на рисках (или их отсутствии), просто потому, что не существует сценария, при котором вы будете свободны от них.
Поэтому, на наш взгляд, лучше всего посмотреть на это следующим образом:
- Рассмотрите бизнес-последствия любого из вариантов. Каковы их потенциальные последствия?
- Проанализируйте и оцените риски. Один из вариантов может быть более рискованным, чем другой, но не обязательно. Понимаете ли вы, что означает тот или иной вариант?
- Изложите причины, по которым вы хотите провести рефакторинг или переписывание. Чего вы хотите добиться?
- Определите, насколько ваше текущее программное обеспечение далеко от этих целей. Сделайте это как можно более подробно.
- Определите четкий путь, который приведет вас от текущего состояния к желаемому. Возможно ли это вообще? Возможно, есть несовместимость с новыми технологиями или нет возможности переделать устаревшее ПО под современное оборудование.
- Разложите оба процесса по этому пути. Что входит в рефакторинг кода? И что входит в переписывание? Это ключевая часть оценки, поэтому не пытайтесь выразить процесс в том, сколько времени, по вашему мнению, займут оба процесса. Вместо этого постарайтесь представить себе задачи и их сложность, поскольку это позволит вам лучше сравнить оба варианта.
- Сравните пути, лежащие перед вами. Возможно, вы увидите, что, хотя рефакторинг может потребовать больше шагов, эти шаги проще, чем те, что включены в переработку. А может быть, становится ясно, что рефакторинг - это непреодолимая задача из-за множества связанных с ним задач.
Получив более четкое представление об обоих путях, проведите переоценку бизнес-движущих факторов и рисков. Учитывая все эти соображения, вы будете лучше подготовлены к принятию окончательного решения.
Спор между рефактором и рерайтом является стерильным, когда речь идет о повседневной работе, поскольку он часто переходит в теоретическую плоскость. Поскольку нет двух одинаковых проектов, очень важно рассмотреть эти практические шаги, чтобы лучше подойти к вопросу и определить, какой путь лучше.
Даже если вы видите, что какой-то подход дает лучшие результаты для ваших проектов, не поддавайтесь искушению выбрать этот вариант по умолчанию, поскольку в конкретном проекте вы можете столкнуться с другим подходом. Может показаться утомительным проводить такой анализ каждый раз, когда вы работаете со старым кодом, но я гарантирую, что только так вы сможете добиться наилучших результатов для своих проектов.