Ремонт нельзя закончить, его можно только остановить.

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

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

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

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

С бизнес точки зрения проблема состоит в том, что:

— существенно увеличивается время на внесение изменений и написание новой функциональности

— соотношение поддержка старого кода / инновации, очень сильно начинает крениться в сторону поддержки

— увеличивается время «въезжания» новых программистов в проект

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

Сначала, опишу три выхода из этой ситуации, а потом обсудим каждый их них:

— сделать кучу маленьких рефакторингов

— переписать все заново

— сделать большой рефакторинг

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

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

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

Плохой код состоит из нескольких частей

— плохая и непродуманная архитектура (написание проекта без продумывания архитектуры наперед)

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

— кучу заплаток поверх архитектуры

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

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

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

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

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

— что конкретно улучшается

— поставить жесткие временные рамки

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

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

Очень важно избежать двух тенденций.

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

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

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

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

13 комментариев to “Ремонт нельзя закончить, его можно только остановить.”

  1. Ну в общем то про это уже много раз писалось, но аналогия с ремонтом мне понравилась.
    И не раскрыта тема по поводу «- кучу заплаток поверх архитектуры».

    Кстати, «архитектура», по моему это ужасно заезженное слово к сожалению.

    • Victor Ronin:

      Ну, а что ж делать, что слово заеженое :)) судьба у него такая.

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

  2. Yuri:

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

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

    • Victor Ronin:

      Согласен на 100%. Рефакторинг — это проект по инвестированию в качество. И идеально вообще считать его ROI. То есть инвестируем X долларов, для того, чтобы снизить затраты на поддержку и в течение года получаем точку безубыточности и т.п.

      Единственное, что мешает это делать, это достаточно сложная процедура оценки качества кода.

  3. >> Единственное, что мешает это делать, это достаточно сложная процедура оценки качества кода.
    Если мерить в целом — да. А вот если разбить на простые составные части? Некоторые из них очень даже просто измеряются:
    — Code Style — сформировали внутренний стандарт и проверили, отвечает код или нет. Есть куча инструментов, которые позволяют это сделать автоматически.
    — Цикломатическая сложность кода (ЦСК) — поставили себе предел, выше которого нельзя подниматься, за исключением «особых» случаев, которые анализируются каждый в отдельности и вперёд.
    — Количество исполняемых строк кода на метод (КИС) — ограничили и тоже проверили.
    Ну, есть ещё пара простых способов оценить качество кода по определённым критериям.
    Кстати, есть какая-то хитрая формула (университет Мэллона, вроде так называется и вроде они разработали), которая ЦСК, КИС ещё какую-то метрику и выставляет общую оценку коду. От неё тоже можно плясать. Эта штуковина, также как и степень покрытия кода юнит-тестами встроенна в MS VS 2008 (это не реклама;)).

    • Victor Ronin:

      Да, безусловно есть методы оценки кода. И кстати, мы собираемся переходить на MS VS 2008 по причине того, что в ней достаточно много встроенных утилит по работе с кодом (в том числе и оценке качества).

      ЦСК и КИС можно действительно посчитать автоматически. А вот например количество «заплаток» или неправильную архитектуру и плохие языковые конструкции очень тяжело оценить автоматически. Ну и естественно, когда нельзя автоматически оценить, то время оценки очень возрастает.

      Немного с боку темы, но просто вспомнилось. Мне знакомый присылает постоянно «перлы» с одного проекта, который ему достался в «наследство».

      И там постоянно конструкции типа:

      for (int i = 0; i < 10; i++) if (i == 5) printf("XXX");

  4. Причем остановить исключительно на время )

  5. Domino:

    Низкая грамотность сильно портит впечатление от неплохой статьи.

    • Victor Ronin:

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

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

        • Victor Ronin:

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