Разработка
Как рефакторинг чуть не разрушил мой брак
Я хочу сказать, что разработчики должны быть гораздо осторожнее в определении понятия «устаревший» и в том, насколько активно они прибегают к рефакторингу.
Да, я обещаю, что эта статья про мир программного обеспечения.
В феврале родители моей жены пригласили нас к себе домой на 2 недели. У нас был 3-месячный ребенок (наш первый), и мы оценили приглашение.
Помощь была потрясающей — у нас наконец-то появилось свободное время, мы хорошо спали и ели вкусную еду!
Под конец я решил, что хочу отплатить за доброту. Субботним утром они все вышли на улицу, и мне пришла в голову отличная идея.
У дома был огромный двор, в котором царил полный беспорядок:
- Кучи мусора
- Повсюду опавшие листья
- В случайных местах брошенные инструменты
- Старые и ржавые ведра
Ее мама всегда жаловалась на беспорядок, поэтому я решил, что моя идея просто гениальна!
Я все убрал — разложил инструменты по полкам, собрал все опавшие листья, выбросил мусор и старые ведра. В результате получилось что-то вроде 5 огромных мешков, полных мусора!
Я принял душ и отправился, как мне казалось, на заслуженный сон.
Представьте себе мое удивление, когда я проснулся от того, что моя жена сказала: «Дорогой, что ты наделал? Мой отец хочет тебя убить!»
Вы поняли, к чему все идет, да?
- Оказалось, что, хотя я и убрал настоящий мусор, я также выбросил компостный уголок, который мой тесть заложил несколько недель назад
- Кроме того, под стратегические места, где водостоки переполнялись во время сильных дождей, были подставлены протекающие ведра, которые распределяли воду более оптимальным образом
- И что самое ужасное, моя свекровь была очень довольна и постоянно говорила: «Посмотрите, какую отличную работу проделал Антон! Вам стоит у него поучиться!»
Но хватит о моих родственниках, давайте вернемся к технологиям.
Почему разработчики всегда стремятся переделывать?
Как часто вы слышали от кого-то из своей команды: «Этот репозиторий в ужасном состоянии, мы должны его отрефакторить!».
Я работаю в 10-летнем стартапе, поэтому недостатка в старых репозиториях и устаревшем коде у нас нет.
Я соглашался с большинством жалоб, и обычно так и поступал — если нам нужно было провести существенную работу в каком-то месте, я включал «приведение его в порядок» в график.
Пока однажды жалоба «этот репозиторий в ужасном состоянии и я не могу ничего понять» не поступила на код, который я сам написал 2 года назад! Он был покрыт юнит-тестами, хорошо документирован и до сих пор активно использовался!
Я был в замешательстве. Неужели я был худшим программистом, чем думал? Посоветовавшись с несколькими людьми из других команд и попросив их просмотреть этот код, я пришел к выводу, что это не моя вина (на этот раз).
С самого начала времен разработчики всегда стремились переписать все заново.
Джоэл Сполки писал в своей замечательной статье 25-летней давности:
Программисты всегда хотят выбросить старый код и начать все сначала — так как считают, что старый код — это хаос. И вот интересное наблюдение: скорее всего, они ошибаются. Причина, по которой они считают старый код беспорядочным, кроется в фундаментальном законе программирования:
Читать код сложнее, чем писать его.
Вот почему повторное использование кода так сложно. Именно поэтому у каждого в вашей команде есть своя функция, которую они любят использовать для разбиения строк на массив подстрок. Они пишут свою собственную функцию, потому что это проще и веселее, чем понимать, как работает старая.
Сегодня вы можете спросить практически любого программиста о коде, над которым он работает. «Это большой страшный беспорядок», — скажет он вам. «Самое лучшее — выкинуть его и начать все с начала».
Это было написано в 2000 году(!), и меня поражает, что это все еще правда. Это может привести к бесконечному циклу — если код, который я написал всего 2 года назад, уже считается «устаревшим», кто даст гарантию, что новый код будет лучше?
Из той же статьи:
Важно помнить, что когда вы начинаете с нуля, нет абсолютно никаких оснований полагать, что вы сделаете работу лучше, чем в первый раз. Вы просто повторите большинство старых ошибок и добавите несколько новых проблем, которых не было в первоначальной версии.
Лучше всего эту концепцию объясняет знаменитая иллюстрация Ману Корне ( на его сайте есть еще много замечательных комиксов!):
Старый код — лучший код
Возвращаясь к истории с задним двором моего тестя (клянусь, это реальность, с тех пор мы помирились, но это пятно останется надолго…) — когда вы пытаетесь переписать кодовую базу, которую не до конца понимаете, вас ждет провал.
Несколько недель назад во время обеда кто-то спросил одного из разработчиков в моей команде, сколько времени займет создание одной из наших внутренних систем с нуля.
Он посмотрел на меня и сказал: «Что-то около 3 месяцев, верно, Антон?».
А я ответил: «Ближе к 6. А потом еще 3 года, чтобы добавить все крайние случаи».
Чем дольше существует код — тем он стабильнее. Когда я начал руководить своей командой 2.5 года назад, мне дали legacy систему для поддержки, которую никто толком не знал. До сих пор у нее всего 2 небольшие проблемы, связанные с внешними изменениями API, и она просто безупречно работает…
Код как вино — с годами все лучше.
Вадим Кравченко написал об этом отличную статью:
Почему вам стоит задуматься о старении кода? Потому что чем дольше ваш код существует, чем больше различных катаклизмов он пережил (читай: изменений в бизнесе) и чем больше эволюционировал, тем он надежнее. Команда, которая создавала его до вас, успела отладить, оптимизировать, улучшить — код накопил за годы множество исправлений, которые находятся там, где вы даже не можете себе представить.
Все ошибки были устранены, и вы получили зрелую, стабильную систему, способную справиться с любыми трудностями.
Поиск баланса
Я не говорю, что код должен жить вечно. Требования меняются, появляются новые технологии.
Я хочу сказать, что разработчики должны быть гораздо осторожнее в определении понятия «устаревший» и в том, насколько активно они прибегают к рефакторингу.
Ваша роль как менеджера заключается в том, чтобы помочь команде найти баланс — представлять разработчиков, бороться за время для рефакторинга, когда вы считаете, что это необходимо, но также представлять бизнес-сторону и давать отпор, если вы считаете, что рефакторинг не является критичным в данный момент.
2 вещи, которые вы должны сделать перед началом рефакторинга:
- Подумайте о будущем. Планируются ли в ближайшем будущем большие фичи в этой кодовой базе? Если нет — подождите их, прежде чем что-то делать, они могут никогда не появиться.
- Приложите настоящие усилия, чтобы понять старый код. Пусть разработчик потратит несколько дней на то, чтобы разобраться в существующем коде. Меня удивляет, как часто проекты по рефакторингу длиной 6-8 недель начинаются с того, что не тратится и дня на то, чтобы понять, что вы пытаетесь заменить! Если через несколько дней разработчик почувствует себя увереннее, возможно, огромный рефакторинг не так уж и срочен.
В следующий раз, когда вы задумаетесь о рефакторинге рабочей кодовой базы, вспомните моего тестя…