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

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

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

Предпосылки


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

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

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

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

А может переписать всё с нуля?


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

А вообще, почитайте Джоэла Спольски. Он дело говорит (хотя, по официальной версии Netscape всё-таки был выбит с рынка бесплатным IE, а не задержками в обновлениях).

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

Итак, как же убедить бизнес, что рефакторинг всё-таки нужен?

Совет 1. Не продавайте бизнесу рефакторинг!


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

Обратим внимание на два пункта:
  • цель рефакторинга – упростить понимание и модификацию кода – чисто техническая, а не бизнесовая
  • поведение не меняется, то есть результат для бизнеса не заметен

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

А теперь представьте себя на месте бизнеса. Команда дорогостоящих специалистов потратила кучу времени на «наведение красоты» вместо того, чтобы делать вполне понятные фичи, которые приносят пользователей и деньги. Это всё равно, что, отдав машину в автосервис, получить её в неизменном виде и счёт на $500 с запиской «мы перебрали вам подвеску и теперь сможем поменять стойки в три раза быстрее. Возможно, первое время будет что-то постукивать, но должно пройти через месяц. Если не пройдёт – приезжайте, мы поправим за умеренную плату». Не знаю, как вам, а мне бы такое не очень понравилось.

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

Тогда что говорить?

Совет 2. Продавайте бизнесу возможности и решение проблем


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

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

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

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

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

Совет 3. Взгляните на разработку со стороны бизнеса


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

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

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

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

Как же эту выгоду показать?

Совет 4. Оперируйте цифрами


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

Для того, чтобы прийти с нормальным численным обоснованием, придётся позаниматься административной работой. Например, собрать в один список все баги, которые не удаётся исправить за разумное время в текущей реализации, и которые исправятся после рефакторинга. Более сложный и кропотливый труд – вести учёт, сколько времени занимает каждое изменение, и к каждой цифре дописывать время, которое занимало бы это изменение в системе после рефакторинга. Это на порядок сложнее, но и результаты даёт гораздо более ощутимые. Потому как, «изменение, которое позволило бы нам сохранить X человеко-часов разработки за последний месяц и позволит экономить примерно столько же в будущем» звучит для бизнеса гораздо понятнее и убедительнее, чем необходимость «привести код в порядок».

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

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

И Удачи!

Комментарии (20)


  1. baldr
    22.09.2015 12:28

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

    — Михалваныч, пора рефакторинг делать!
    — Да? А долго?
    — Ну за три недели можно успеть.
    — У, @$#%! А что поменяется?
    — Ну для клиентов ничего, но…
    — Так, никакого рефакторинга, давайте баги чините лучше!

    Лучше действовать осторожнее:

    — Семен, надо добавить кнопку чтоб сервера перезагружать удобнее.
    — Михалваныч, три дня.
    — @$%%";"%!!! Как три дня? Это ж просто кнопка! А если попрошу просто цвет поменять — ты скажешь что неделю?
    — У нас очень сложный код. Если его переписать, то потом можно будет за полчаса все делать.
    — Хмм, ну хорошо, сейчас не будем, но я подумаю.

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


    1. Delphinum
      22.09.2015 14:36
      +4

      Пробовал, на деле Михалваныч как и вы, три-пять раз открещивается словами «подумаем».

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


      1. baldr
        22.09.2015 17:42
        +3

        То есть вы фактически делаете рефакторинг, но без одобрения руководства и включаете это время в разработку одобренных фич.
        Это тоже способ и, наверное, самый спокойный для нервов. Пока не узнает начальство.
        В моем опыте Михалваныч был в меру адекватным и раз в год время на рефакторинг по «техническому долгу» нам выделялось — недели три-четыре (целый спринт) на рефакторинг плюс пара мелких фич бонусом.


        1. Delphinum
          22.09.2015 18:20

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

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


        1. Bronx
          23.09.2015 03:41
          +1

          Принцип «проще получить прощение, чем разрешение» хорошо работает как раз в таких случаях нерешительного начальства.


    1. Flammar
      22.09.2015 19:18

      Ну то сам выступаешь с инициативой, а то подталкиваешь начальство к дозреванию во вопросу…


  1. Dywar
    22.09.2015 18:58
    +1

    Остается вопрос — кто виноват.
    Это как учебники в школе, получаешь исписанные и порванные а возвращаешь чистые и подклеенные. И это не прекращается ни для тебя, ни для тех кто после тебя.


    1. Tomcat
      23.09.2015 10:15
      +1

      Если каждый год новый легаси-проект, то только идти с евангелистикой — писать книжки, статьи на хабр :), на конфах выступать — и всех убеждать, что надо писать чистый код.

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


  1. ivanych
    22.09.2015 20:22
    +2

    Во всей этой ситуации с рефакторингом мне всегда виделось какое-то нелепое противоречие.

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


    1. NightGhost
      22.09.2015 20:48
      +4

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

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


      1. ivanych
        22.09.2015 21:25

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

        Это не выгода разработчика. Рутинная или не рутинная работа — разработчику всё оплачивается одинаково, а выгода тут бизнесу.

        > развитие себя как разработчика, стремящегося к хорошему коду, навыки разбора чужого кода и облагораживания его

        Ага:) Навык рефакторинга, чтобы потом доказывать бизнесу, что ему нужен рефакторинг. Замкнутый круг.

        >Когда я вижу узкие/стремные места, я хочу привести их в порядок, хочу отрефакторить их.

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


        1. baldr
          22.09.2015 21:45
          +4

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

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

          1. Нарисовать кнопку на форме (поиграться со стилями чтоб не съехало из-за таблиц), добавить обработчик на UI, добавить получатель события на бэкенде, захардкодить семь констант, отправить три сообщения и добавить sleep'ов чтоб получить ответ, реализовать саму операцию (документацию читать некогда, сделаю все сам), отладить, мат, починить, отладить, кофе, отладить, мат-кофе-мат-кофе, починить, починить, починить…

          2. Просто добавить тип операции «reboot» в массив операций на UI (нарисует кнопку само, отрендерит, добавит стандартный обработчик), а на бэкенде из очереди сам заберет демон и все отработает (эта операция поддерживается движком, еще полгода назад с Серегой сделали).

          В результате во втором случае мы помним что все нужно сделать в одном (максимум двух) местах.
          А в первом случае мы затронули половину файлов проекта, голова пухнет — все не запомнить, местами лапша из таких же if'ов, которые остались от прошлого разработчика (интересно почему он уволился так быстро?), один тест не проходит (его пока отключим), а в комнату входит Михалваныч с задачей по еще одной кнопке.

          В итоге получаем дергающийся глаз и недовольное начальство (первый случай) или грамоту за быструю работу (второй).


        1. NightGhost
          23.09.2015 00:44
          +2

          Это не выгода разработчика. Рутинная или не рутинная работа — разработчику всё оплачивается одинаково, а выгода тут бизнесу.

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

          Ага:) Навык рефакторинга, чтобы потом доказывать бизнесу, что ему нужен рефакторинг. Замкнутый круг.

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

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

          Все зависит от подачи.
          «Мэмэмэ, мне тут нужно отрефакторить, чтобы мэмэмэ» — конечно будут палки в колеса. Бизнес не понимает, нафига это вообще надо.
          «Коллеги, мне нужно потратить два дня на рефакторинг функционала расчета прайсов, но зато мы с вероятностью в 80% перестанем ловить постоянные баги, плюс время модернизации функционала (а мы его модернезируем постоянно) увеличится примерно на 40%. То есть затраты на рефаторинг отобьются в течении месяца, и в дальнейшем будем только экономить.» — и вперед.


          1. Delphinum
            23.09.2015 01:12
            +2

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


          1. summerwind
            23.09.2015 04:09
            +2

            мы с вероятностью в 80% перестанем ловить постоянные баги… время модернизации функционала (а мы его модернезируем постоянно) увеличится примерно на 40%

            Честно говоря, больше похоже на речь ясновидящего, а не программиста) Не очень люблю давать такие громкие обещания менеджменту, потому что потом, чуть что, обязательно будут фразы «ну ты же говорил...», «уже два бага за неделю, а ты обещал...».
            А если, действительно, сидеть и подробно анализировать, что время разработки увеличится именно на 40%, а не на 30, то как тут уже писали, на это времени может уйти как на сам рефакторинг :)
            Я считаю, что лучший вариант — это когда бизнес и разработчики знают, как найти общий язык и хоть немного вникают в проблемы друг друга, а не живут в параллельных измерениях.


            1. baldr
              23.09.2015 08:53
              +1

              Боюсь, что какие-то количественные оценки вы все-таки должны будете выдать. Качественные оценки не катят.
              Бизнес не устроит фраза «будет лучше», их всегда интересует «насколько лучше».


            1. Tomcat
              23.09.2015 10:19

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


              1. funca
                23.09.2015 11:19

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


        1. VolCh
          23.09.2015 15:51
          +1

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

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


  1. MrEsp
    05.10.2015 09:41
    +1

    спасибо за интересную статью! Имхо, самый безопасный в ожидаемой ситуации способ — закладывать стоимость рефакторинга в стоимость change request'а. Но, на моей практике были и случаи, когда непосредственно заказчику приходилось объяснять, почему нужно прямо сейчас делать рефакторинг, почему не через 2 месяца и к чему приведет обратное. В условиях наличия «компьютерной грамотности» со стороны заказчика, убедить в целом можно. К сожалению, для многих заказчиков (которые этой КГ не имеют), внедрение информационных систем и их разработка — это есть большой черный пузырь, который внешне не отличается, например, от строительства бань или продажи товаров по интернету. Построили вам баню, а потом приходят и говорят «вы знаете, архитектура этой бани недолговечна, нужно бы перелопатить все бревна». Тут ни о каком рефакторинге лучше вообще не упомянать.