Рефакторинг без отрыва от производства: пьеса в трех частях

Мы записали историю от Алексея Катаева, руководившего разработкой интерактивной платформы для обучения английскому - основного продукта Skyeng. Эту платформу давным-давно начали писать еще основатели на JQuery и пятом PHP, а сейчас она живет на четвертом Symfony и восьмом Angular. За все это время ее ни разу не переписывали с нуля.

Основано на реальных событиях
Основано на реальных событиях

— Леша! Давай перепишем все с нуля! Здесь уже отрефакторить ничего нельзя! — С таким предложением ко мне приходят Дима и Катя, это мои разработчики.

— Ну так а что ж вы не рефакторили все это время?

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

И, естественно, предложение Димы и Кати отклоняется. Но проблема остается!

Видеоверсия истории для тех, кто больше любит слушать, чем читать

Глава первая, где мы договариваемся с Глебом

Мы вместе с Димой и Катей отправляемся говорить с Глебом. Поскольку у нас в Skyeng разработчики разбросаны по всему миру и работают удаленно, встречаемся мы в Hangouts.

— Глеб! — Говорят Дима и Катя. — Если мы будем и дальше быстро пилить фичи и не будем рефакторить, у нас будет плохой код!

— Ну и что, что плохой? Зато он приносит деньги, — парирует Глеб.

Не получилось. Ладно, пробуем зайти с другой стороны:

— Глеб! Если мы будем быстро катить фичи, то в конце концов наш проект ждет катастрофа!

— Ооо, быстро катить фичи? — Оживляется Глеб. — Да! Я как раз хотел на этой неделе проверить 10 гипотез; они должны принести много денег.

Вот такой у нас Глеб, все у него только деньги на уме. За это его и ценят, собственно. Коли так, попробуем задеть его за живое:

— Глеб! Если мы не будем рефакторить, мы не сможем быстро проверять гипотезы и впиливать твои прекрасные новые фичи, должные принести много денег. Если мы не будем рефакторить, стабильность нашего проекта упадет, у нас будет куча багов, мы начнем терять деньги. Глеб! Скоро мы не сможем нанимать классных разработчиков, мы будем тратить на их поиск кучу денег, а они будут приходить и говорить “да не хочу я работать с вашим плесневелым легаси!”. А если уйдут Дима и Катя, это вообще будет катастрофа.

Рефакторинг без отрыва от производства: пьеса в трех частях

Но это не все: перед тем, как мы пошли к Глебу, я дал Диме и Кате почитать книгу “Договориться можно обо всем!” Гэвина Кеннеди. Они знают, что мало просто напугать Глеба, надо выдвинуть конкретное предложение:

— Глеб! Давай будем тратить на рефакторинг 20% времени! Только в этом квартале, а в следующем, когда разберемся с основными проблемами, - всего 15%! А взамен мы предлагаем тебе Изолированные Костыли™!

— Окей, — наконец говорит Глеб. — 20% мы можем себе позволить, особенно если благодаря этому мы не будем терять деньги.

Почему у нас получилось?

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

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

— Ну что, Дима и Катя, теперь у нас 20% времени на рефакторинг!

Но Дима и Катя почему-то в задумчивости:

— А что же мы будем делать с фичами, которые не докатились, что же делать с критичными багами, которые срочно нужно фиксить?..

Уходят думать и возвращаются с предложениями:

— Давайте откусим 20% от квартала одним блоком и будем в это время сфокусированно рефакторить, — предлагает Дима.

— Погоди, Глеб ни за что на это не пойдет. Он скажет: “Как мы можем остановить производство наших фич и проверку гипотез?” А вариант отложить это на конец квартала не сработает, там всегда найдется, что делать, плюс времени, конечно, не останется.

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

— Катя! Тогда мы будем рефакторить только какие-то мелочи и не сможем сделать крупный рефакторинг. Кроме того, если мы будем говорить Глебу, что у этой задачи time to market 16 часов, а не 10, мы будем обманывать Глеба. Вот тебе, Катя, книга Сэма Харриса “Ложь”, в ней говорится о том, что в долгосрочной перспективе говорить правду всегда выгоднее. Твой вариант тоже не катит!

Что же остается?

Остается рефакторить параллельно с разработкой. И для сначала понять

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

Допустим, мы посчитали часы, вычли отпуска, перемножили на разработчиков и получилось у нас условные 100 часов разработки в месяц. Значит ли это, что теперь мы 20 из них будем тратить на рефакторинг?

Нет.

Статистика собрана с реальной команды
Статистика собрана с реальной команды

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

Итак, Катя и Дима взяли задачу, рефакторили честные 13 часов в начале месяца, а потом отправились привычно тестировать гипотезы и выкатывать фичи. Наступил конец месяца, и что? Как всегда, что-то где-то зафакапилось, приходит Глеб:

— Что-то вы много рефакторите, не успеваете работать над продуктом, давайте отменять.

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

Команда рефакторила 31% времени. Что скажет Глеб?)
Команда рефакторила 31% времени. Что скажет Глеб?)

Окей, мы определились, когда рефакторить. Теперь надо решить,

Что именно рефакторить

Катя и Дима предлагали нам переписать все с нуля.

— Нет, ребят, переписывать с нуля мы не будем.

— Почему?

— А потому, что у нас есть принцип 2.15:

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

— Мы будем бороться с техническим долгом.

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

— Нет, это нам не подходит. Мы тогда вообще не будем видеть света в конце тоннеля, ведь у нас бесконечное число проблем.

— Ну давай ты составишь нам список самых критичных, будем работать с ними!

Проблема в том, что код я давно уже не пишу, поэтому смутно представляю себе, какие там в нем на самом деле проблемы. А кто представляет? Конечно, разработчики - Катя с Димой! Пусть сами их и перечисляют.

Делаем доску в Трелло и говорим:

— Народ, пусть каждый напишет сюда карточки с проблемами, которые видел: костыли, кривые решения, старые библиотеки, старые API и т.д.

Когда я впервые провел такое в команде биллинга, то получил примерно такие карточки:

Что это и как с этим жить?
Что это и как с этим жить?

Ввели соглашение писать карточки в определенном формате:

  • Проблема, которую решаем;
  • Профит, который получим;
  • Если есть, возможное решение.

Дальше собираемся на встречу и обсуждаем, что с этим всем делать: это у нас называется рефакторинг-митап. Ищем максимально высокоуровневые решения, создаем тикеты в Jira - есть у нас специальный тип таких тикетов refactoring task.

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

Рефакторинг без отрыва от производства: пьеса в трех частях

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

Итак, нам потребовалось:

  • Понять, что рефакторить надо параллельно. Раз в квартал или обманом (завышением оценки) - плохие варианты;
  • Прежде чем бороться с проблемой, ее надо формализовать;
  • Приоритезировать: не прыгать на коня и скакать шашка наголо, а сперва найти самые больные места.

Глава третья, где мы учимся делать так, чтобы больше никогда не рефакторить

Опять пришли Дима с Катей:

— Леша! Кажется, мы попали в какой-то бесконечный водоворот. Мы пилим фичи - рефакторим, пилим фичи - рефакторим, и нет из этого никакого выхода.

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

Пицца-клуб. Совершенно элитный закрытый vip-клуб, члены которого должны прочитать книгу, сделать по ней презентацию на пять минут для своей команды и за это получить пиццу с доставкой на дом. Филонишь? Тебя ждет страшное наказание: исключение из vip-клуба!

Education Day. В советских НИИ это называлось “библиотечным днем”: выделяем разработчику целый оплаченный день, даем список статей (или выбирает сам), он их читает и по итогам публикует обзор - что получил, чему обучился, рекомендует ли команде. Эдакий полу-выходной. Наш опыт говорит, что это действительно работает.

Таблички. Я люблю таблички.

— Здравствуй, команда, напиши мне в этой табличке, насколько каждый из вас разбирается в приеме платежей, поиске сотрудников и расчете зарплат:

Рефакторинг без отрыва от производства: пьеса в трех частях

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

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

Боты. Мы автоматизировали процесс технического ревью. У нас есть бот Джейк: каждое утро он собирает задачи на разработку и проводит опрос “Кто хочет обсуждать вот эту задачу”. Голосуют “за” те, кто шарит в задаче, разбирается в теме, либо им просто очень интересно поучаствовать. Количество участников ограничено четырьмя, потом формируется расписание и проводятся встречи.

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

Эпилог

Итак, Дима с Катей счастливы, потому что мы:

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

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

55
Начать дискуссию