Code review — долго, плохо, дорого

В этой статье я попытаюсь подытожить обсужденную в Podlodka Crew с Филом Дельгядо, Виктором Фабриченко, Олегом Сорокой, Виталием Дмитриевым, Родионом Кривошеиным и Александром Агейченко тему эффективности практики код ревью в производстве программного обеспечения.

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

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

Начну с того, для чего код ревью используется чаще всего.

С небольшими вариациями код ревью используется в более-менее похожем процессе разработки, состоящим из следующих шагов:

Цели ревью кода

Обычно при использовании обязательного code review хотят (по крайней мере рассказывают, что хотят) примерно это:

Цена ревью кода

Любая процессная активность для того, чтобы достигать своей цели, требует траты времени.

В процессной активности «ревью кода» трата времени разделяются на 4 основных категории:

Время на саму практику

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

Важно: общая трата времени кратна числу ревьюверов.

Время на доработку

В зависимости от того, насколько много изменений требуется сделать в задаче после ревью, время на доработку может достигать очень больших значений — порой до 70-80% от потраченного изначально.

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

Время переключения контекста и обсуждения

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

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

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

В случае, если регламент компании после исправлений замечаний подразумевает еще один этап ревью кода, происходит еще два переключения контекста у ревьювера.

Если взять время переключения контекста за 15 минут, то:

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

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

Время простоя задачи

В процессе разработки задача, переведённая на ревью, может ожидать ревью значительное время, увеличивая тем самым lead time на количество часов простоя. Некоторые компании вносят в регламент процессов разработки требование ожидания ревью не более Х часов, что приводит к увеличению частоты переключения контекстов сотрудников, тем самым “размазывая” увеличение lead time конкретной задачи между несколькими сотрудниками.

Время на слияние веток после ревью

В связи с тем, что задача, находящаяся в процессе код ревью, часто простаивает довольно долго, слияние ветки задачи с мастером может занять значительное время.

Есть статья товарищей из SkyEng https://habr.com/ru/company/oleg-bunin/blog/430666/ , где они рассказывают, что 37% времени тратят на встречи и ревью, а еще 20% на баги и рефакторинг.

Дополнительные факторы, увеличивающие цену практики

Есть несколько факторов, которые провоцируются или привносятся практикой ревью кода. Эти факторы увеличивают общую цену практики.

Выброшенный труд

К моменту передачи задачи на ревью исполнитель ощущает, что он проделал значительную работу — проанализировал постановку задачи, написал код. Есть подспудное ощущение “сделанности”.

Когда по результату ревью оказывается, что нужно произвести множество изменений в задаче, а то и, порой, переписать её почти с нуля, у исполнителя возникает ощущение, что его работа “выкинута” и, порой, что она была бессмысленна.

Наверняка вам приходилось убеждать сотрудника, что этот процесс “нормален”, что “через это все проходят”.

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

Бороться с ощущением “выкинутого” или “бессмысленного” труда довольно трудно, демотивирующий фактор здесь довольно серьёзен.

Ad hominem

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

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

Разница в стилевых предпочтениях, «войны за стиль»

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

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

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

Привычка делать тяп-ляп

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

Также сам процесс обучения становится неэффективным — человек сначала написал неправильно (отложилось в памяти), потом что-то частично поправил (не факт, что отложится так же).

Заодно уменьшается ответственность сотрудника и за простои в разработке — “а оно на ревью висело вон сколько, они задолбали фигню находить”.

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

Вывод

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

Замена код-ревью

Рассмотрим замену практики код-ревью другими инструментами, позволяющими достичь всех целей, что ставятся перед код-ревью.

Сделать код понятнее

Проверки code style должны перекладываться на линтеры.

Люди традиционно имеют различные преференции по оформлению кода.

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

Тем самым мы избегаем вечных «войн пробелов с табами», программными средствами нивелируя пробле полностью.

Для javascript, например, дело решается eslint + prettier + husky.

Избежать ошибок

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

Уменьшить bus-factor

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

Обменяться знаниями

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

comments powered by Disqus