Отрезок качества
Есть принцип «выбирай любые два понятия из «быстро, качественно и дёшево». Да, он верен для проектных историй, но не верен для разработки. В разработке, как процессе, нет никакого треугольника качества. Ты можешь делать либо быстро и качественно, либо медленно и плохо. И нет ни одной причины выбирать «медленно и плохо (и на самом деле еще и дороже)», если только не в силу привычки и неосознанности.
»Как же так? Я тысячу раз забивал на тесты и проектирование, и быстро выкладывал в прод. Я делал похуже, но задача быстрее попадала на прод или в тестирование». На самом деле ты просто быстрее выложил задачу на прод, но не быстрее сделал задачу. Мы заканчиваем задачу тогда, когда к ней уже не нужно обращаться, когда она работает и не требует внимания разработчика. А если после выкладки — через день, два, да даже через неделю или месяц, — приходится срочно править баги, тушить пожары и переписывать код, то мы всего лишь выложили быстрее, но отнюдь не сделали быстрее. И более того, мы потратили гораздо больше усилий. Сравните «сделать спокойно и выкатить на день позже» с «выкатить на день раньше и потом еще 2—3 дня тратить на баги, отвлекая разработчика, срывая текущие планы и переключая контекст».
Когда ты спешишь, суетишься и выкатываешь быстрее, ты на самом деле себя обманываешь. Ты делаешь хуже. Мы тестируем свой код не для того, чтобы себя занять, а чтобы удостовериться в том, что на выходе получится то, что требуется. Мы пишем автотесты не потому, что это прикольно и мы прочитали очередную книжку про TDD, а потому, что они сокращают цикл обратной связи «написал/поправил», и в конечном счёте ускоряют разработку. Мы проектируем API или архитектуру не для того, чтобы чувствовать себя генералами UML, а потому что подумав чуть-чуть в начале, нам не придётся в конце всё переделывать, и дальнейшие правки будут проще.
Конечно, тебе будут рассказывать про Петю, который накостылял, а потом переписал, когда проверил продуктовую гипотезу. Но как часто вы переписываете после проверки гипотезы, если она выстрелила? Как часто эти временные, быстрые и костыльные решения определяли судьбу всего проекта и оставались на долгие годы, отравляя разработку не одному поколению инженеров и разработчиков?
»Это же не эффективно — тратить время на написание супер-универсального или супер-производительного кода.» И нет, качественная работа — это не про супер-универсально, или супер-производительно, или супер-безопасно, или pixel perfect. Качественная работа — это адекватный задаче, продукту и команде уровень универсальности, производительности, безопасности и протестированности кода. Искусство разработки и состоит в том, чтобы найти такое техническое решение, которое можно было бы реализовать в рамках имеющихся ограничений: продуктовых, ресурсных, временных, инженерных, с учётом всей неопределённости.
Слишком сложное решение — это не качественное решение. Неработающее решение — это тоже не качественное решение. Если ваш процесс разработки приводит к багам, к плохо поддерживаемому коду, если его невозможно успешно масштабировать, то это плохой процесс. Чем больше плохого кода рождает плохой процесс разработки, тем больше будет проблем, и тем сложнее и сложнее будет выбраться из ямы.
А самое страшное, что снижая планку инженерного качества мы учимся делать хуже. Я много раз видел, как люди, которые привыкли писать код через костыли, побыстрее, даже когда у них много времени, не способны писать код по-другому. Концепция «пока стартуем проект, сделаем по-быстрому, а потом переделаем хорошо» на самом деле не работает. Потому что инженерная культура — это вторая натура, это привычки, и от них крайне тяжело избавиться. Если человек делает хорошо, качественно, то он не может начать делать плохо по щелчку пальцев. Попробуйте сами написать плохой код — вы потратите значительно больше усилий, чем на хороший. У такого человека уже огромный багаж хороших, качественных решений, подходящие для этого инструменты. То же самое касается и тех, кто всегда делает по-быстрому: они также по щелчку не смогут начать писать нормальный код. Хотя им может так и казаться.
Если же говорить про изменения в процессах командной разработки, то здесь всё работает ровно наоборот: сначала учимся делать качественно, хоть и дольше, а потом, не снижая качества, ускоряемся за счёт перехода осознанных практик в подкорку мозга. И эта история масштабируется.
Я не стану и не советую писать код плохо, нарушать производственный процесс, чтобы сэкономить полчаса, а потом два дня разбираться с багами. Потому что привычка — это вторая натура. И ты либо работаешь хорошо и быстро, либо плохо и медленно. Тесты, рецензирование кода, проектирование, общение с заказчиком, написание кода — это всё инженерный процесс. Если попытаться его сократить, оптимизировать и выкинуть неотъемлемые части, то мы получим плохой процесс, который будет ухудшать продуктивность разработки. Я даже не могу себе представить, от каких инженерных практик я могу отказаться, чтобы писать код хуже, но быстрее. Править код в проде? Отказаться от запуска тестов? Отказаться от написания тестов? Отказаться от продумывания архитектуры и API? Отказаться от CI/CD? Мониторинга и алертинга?
Что делают спортсмены, например, тяжелоатлеты или бегуны? Нарушают ли они технику, чтобы побыстрее пробежать, больше рвануть и толкнуть? Иногда, в очень редких случаях — да. Но практически всегда техника важна, потому что она даёт результат, а отсутствие техники приводит к травмам (инцидентам) и худшему результату. И в момент стресса и напряжения, например, на соревнованиях, очень хочется скруглить углы и сделать побыстрее, но нельзя: это как раз тот самый момент, когда соблюдение техники важнее всего. В моменты пожаров и психологического напряжения всегда есть большой соблазн отказаться от тестов, CI/CD, рецензирования кода или продумывания решения, но именно в эти моменты дисциплина и твёрдость могут принести максимальную пользу.
И где же мы наберём этих суперменов, которые всё знают и умеют? На самом деле, не обязательно всё знать и уметь, достаточно иметь хорошие инженерные практики, вошедшие в подкорку. Первое, что, например, делают с новичками в спортзале, это ставят им технику. Точно так же мы должны поступать с джунами: ставить им технику. Да, они не смогут поднять какую-то сложную задачу, но простую, соответствующую их компетенции, они будут делать быстрее и лучше. Поэтому нам не нужно нанимать суперменов за безумные деньги, в команде достаточно грамотного «тренера», который всем поможет не «срывать спину» и прогрессировать.
P.S.: классическая статья Мартина Фаулера на эту же тему