Что такое code review
Еще одна статья о code review
Что такое code review
Что можно инспектировать
Для ревью подходит любой код. Однако, review обязательно должно проводиться для критических мест в приложении (например: механизмы аутентификации, авторизации, передачи и обработки важной информации — обработка денежных транзакций и пр.).
Также для review подходят и юнит тесты, так как юнит тесты — это тот же самый код, который подвержен ошибкам, его нужно инспектировать также тщательно как и весь остальной код, потому что, неправильный тест может стоить очень дорого.
Как проводить review
Вообще, ревью кода должен проводиться в совокупности с другими гибкими инженерными практиками: парное программирование, TDD, CI. В этом случае достигается максимальная эффективность ревью. Если используется гибкая методология разработки, то этап code review можно внести в Definition of Done фичи.
Из чего состоит review
Также очень важно определиться, за кем будет последнее слово в принятии финального решения в случае возникновения спора. Обычно, приоритет отдается тому кто будет реализовывать код (как в scrum при проведении planning poker), либо специальному человеку, который отвечает за этот код (как в google — code owner).
Как проводить design review
Design review можно проводить за столом, в кругу коллег, у маркерной доски, в корпоративной wiki. На design review тот, кто будет писать код, расскажет о выбранной стратегии (примерный алгоритм, требуемые инструменты, библиотеки) решения поставленной задачи. Вся прелесть этого этапа заключается в том, что ошибка проектирования будет стоить 1-2 часа времени (и будет устранена сразу на review).
Как проводить code review
Можно проводить code review разными способами — дистанционно, когда каждый разработчик сидит за своим рабочим местом, и совместно — сидя перед монитором одного из коллег, либо в специально выделенным для этого месте, например meeting room. В принципе существует много способов (можно даже распечатать исходный код и вносить изменения на бумаге).
Pre-commit review
Данный вид review проводится перед внесением изменений в VCS. Этот подход позволяет содержать в репозитории только проверенный код. В microsoft используется этот подход: всем участникам review рассылаются патчи с изменениями. После того как собран и обработан фидбэк, процесс повторяется до тех пор пока все ревьюверы не согласятся с изменениями.
Post-commit review
Данный вид review проводится после внесения изменений в VCS. При этом можно коммитить как в основную ветвь, так и во временную ветку (а в основную ветку вливать уже проверенные изменения).
Тематические review
Можно также проводить тематические code review — их можно использовать как переходный этап на пути к полноценному code review. Их можно проводить для критического участка кода, либо при поиске ошибок. Самое главное — это определить цель данного review, при этом цель должна быть обозримой и четкой:
Результаты review
Сложности при проведении review (субъективное мнение)
Основная сложность, с которой мы столкнулись, когда внедряли review в первый раз: это невозможность контроля изменений по результатам review. Отчасти это связано с тем, что данная практика применялась без других практик — CI (это еще раз доказывает тот факт, что все инженерные практики должны применяться вместе).
Утилиты для review
Вообще, утилит для проведения review существует большое количество, как платных, так и бесплатных. Я не стал их приводить, чтобы не навязывать свою точку зрения, в интернете можно найти множество инструментов и подробное описание.
Ссылки
Пожелания, дополнения, критика приветствуется
Что такое код-ревью
Это проверка кода на ошибки, неточности и общий стиль программирования.
Послушать аудиоверсию этой статьи (6 минут):
Слушайте Что такое код-ревью на Яндекс.Музыке
Ситуация: вы разработчик. Вы отвечаете за свой фронт работы, например, за отправку данных на сервер. У команды уже есть готовый проект, вы вместе его поддерживаете и постоянно улучшаете.
Когда вы пишете новую функцию, она не попадает сразу в проект. Вместо этого ваш код отправляется на код-ревью (code review).
Что делают на код-ревью
Во время код-ревью кто-то из старших товарищей изучает ваш код на предмет:
Если проблемы есть, проверяющий отправляет код на доработку. Если всё хорошо, код переходит на следующую стадию — как правило, в тестирование.
Кто проводит
Обычно принято так: код-ревью делают программисты более старшего уровня. Джуниоров проверяют мидлы, мидлов — сеньоры, сеньоров — другие сеньоры или тимлиды. Если компания большая, то могут выделить отдельно несколько человек, которые смотрят код у всех и следят за общим стилем.
Если команда небольшая, то код-ревью делает ведущий программист — он сам следит за проектом и за качеством кода, который пишут остальные.
Как это выглядит
Зачем это нужно
Если вы пишете один или с другом, то, скорее всего, вам это не нужно. Вы и так можете обсудить код между собой и понять, как его сделать лучше.
Когда в команде программистов много, то компания сталкивается с тем, что все пишут по-разному. И даже если весь этот код работает, его потом нужно поддерживать, а ковыряться в чужом коде, если он плохо написан — это долго и дорого. Поэтому на этапе код-ревью разработчики делают так, чтобы им же позднее было проще поддерживать код и ничего не ломалось.
May the Code Review be with you
Code review может быть большой болью для команды, которая только начинает его внедрять. Вы в любом случае наступите на много граблей: будете проводить ревью дольше, чем пишете код, устраивать смертельные споры про расположение скобочек и разбираться, можно ли сливать ветку в master до аппрува команды или нет. Я собрал ряд практик, которые помогут вам сделать процесс адаптации чуть менее болезненным — по крайней мере, мне они точно помогли.
Этот материал — краткая выжимка моего опыта, накопленного за несколько лет работы в крупных командах мобильной разработки. Опыт по большей части в мобильной разработке, что оказало влияние на используемые примеры и ссылки. Для тех, кто предпочитает не читать, а смотреть, в течение пары месяцев должно появиться видео с конференции Mobius, где я рассказываю доклад на эту же тему, но с кучей подробных практических примеров.
Цели Code Review
Для начала тезисно обозначу цели, которые стоит преследовать при проведении инспекций кода. Именно этими целями и их приоритетом относительно друг друга я и руководствуюсь, советуя внедрять ту или иную практику.
Модели организации Code Review в разных командах
Команды бывают разные — где-то в одном отделе сидит тридцать человек, которые разрабатывают один проект, а где-то разработчик в одиночку поддерживает сразу десяток приложений.
Небольшая команда
Первый случай, наверное, самый часто встречающийся. Это команда из нескольких человек — скажем, до четырех, которые работают над одним проектом. Здесь уже обычно вовсю расцветает Git Flow, задачи разрабатываются независимо друг от друга в отдельных ветках, а по окончании сливаются в develop.
В таком случае лучше всего взлетает модель, при которой для слияния ветки с задачей в основную рабочую ветку требуется одобрение всех участников команды. Это помогает получить максимальные преимущества по всем перечисленным в первом разделе целям проведения ревью.
Несколько отдельных команд
Масштабируем предыдущую ситуацию и представим крупного аутсорсера, в которого входят несколько таких маленьких команд, каждая из которых работает над своим собственным проектом. В таких ситуациях иерархическая структура обычно усложняется и, помимо наличия ведущих разработчиков в каждой из команд, добавляется новая прослойка, тимлид или техлид, который отвечает сразу за несколько таких проектов.
Основной подход остается неизменным — на все новые задачи создаются ревью, в которых принимает участие вся проектная команда, но итоговую ответственность за принятые технические решения несет ведущий разработчик. Кроме того, к важным ревью нужно подключать еще и лида — таким образом он будет оставаться в курсе дел, происходящих на проекте и в нужный момент подключаться к решению возникающих проблем.
В нагрузку идет еще одна дополнительная активность — очень эффективными показывают себя периодические кросс-проектные ревью, когда разработчик знакомится с остальными проектами. Это позволяет каждому быть в общих чертах в курсе того, где какие технологии и подходы используются, знать, кто и в чем разбирается. Подходить к кросс-проектным ревью можно по-разному — вести сквозной перечень всех проектов и сортировать его по последнему ревью, или ставить каждому разработчику цель — раз в определенный промежуток времени инспектировать все остальные проекты. Такие ревью проводятся в основном в ознакомительных целях — поэтому обычно одобрения стороннего ревьюера не требуется для того, чтобы завершить задачу — человек, который смотрит код, перенимает опыт у других команд.
Большая команда
Еще одна ситуация — большая команда, работающая над одним крупным проектом. В такой ситуации хорошо оправдывает себя установление определенного порога ревьюеров, после одобрения которых можно сливать ветку. Это значение может зависеть от размера команды, но разумные рамки — 2-4 человека.
Большим вопросом остается определение конкретных ревьюеров — они могут выбираться как рандомно, кто первый откликнется, так и специально автором ревью. Можно автоматизировать этот процесс, чтобы избежать споров и быть более объективными. Как пример — определять владельца кода по данным истории системы контроля версий или системы для code review.
Разработчик-одиночка
Последний случай — самый грустный. Разработчик работает один в команде. Во-первых, сразу отпадает такая цель, как коллективное владение кодом — нет коллектива, нет и владения. Остальные цели тоже становятся довольно вырожденными — но, тем не менее, сторонний взгляд на код поможет найти часть ошибок и повысить технический уровень в целом.
В таком случае разработчику нужно обращаться за помощью в открытое сообщество. Я советую три канала.
Практики проведения Code Review
Работа по расписанию
Основная проблема заключается в таком понятии, как состояние потока, из которого вырывать разработчика — смерти подобно. Сами представьте ситуацию: вы с головой погрузились в разработку своей фичи, строите в голове дворцы абстракций, и неожиданно за плечо робко трогает коллега и просит взглянуть на его код. Ничего хорошего из этого не выйдет — разработчик и своей задачей не может больше нормально заниматься, и для ревью слишком предвзят и раздражен.
Решает ситуацию расписание. Каждый разработчик в команде определяет промежуток дня, в который он будет смотреть ревью. Расписание всей команды можно держать в одной таблице, чтобы, ориентируясь на это, можно было подбирать себе ревьюеров или рассчитывать время проверки задачи. Я, к примеру, всегда выделял час времени с утра, сразу после прихода на работу — как раз помогало войти в рабочий ритм.
Конечно, есть случаи, когда этот механизм не работает — некоторые ревью действительно нужно смотреть максимально быстро. Главное — придерживаться такого режима, чтобы возникновение подобных ситуаций не становилось привычкой.
Архитектурные review
Я уверен, что вы сталкивались с ситуацией, когда после реализации задачи выясняется, что нужно было ее сделать абсолютно по-другому. Code Review — не самое подходящее место, чтобы спорить по поводу глобальных архитектурных решений. Код уже написан, задача почти доделана, переписывать все с нуля — слишком затратно. Такие вещи нужно не оставлять на потом, а обсуждать заранее.
Как вариант — проведение архитектурного review, защиты своего компонента перед командой либо на словах, либо в виде схемы. Конечно, бывают случаи, когда кого-то осеняет уже во время ревью — тогда это предложение, если оно действительно ценное, стоит задокументировать в issue-трекере и никогда к нему больше не возвращаться.
В качестве участников можно привлекать технического лидера проекта, разработчиков, непосредственно заинтересованных в реализации этой задачи, и просто всех желающих из команды.
Ограничение размера review
Есть один замечательный парадокс — чем меньше кода на review, тем больше к нему оставляется комментариев. Это правило остается неизменным практически в любой команде. Для нескольких строк кода характерно наличие огромных и развесистых дискуссий. При увеличении объема изменений до нескольких тысяч строк количество комментариев резко падает до отметки одного-двух, на которой и остается.
Эта практика очень простая — нельзя отправлять на ревью слишком много изменений за раз. Это требование вполне коррелирует со стандартными правилами по декомпозиции задач, каждая из которых не должна превышать рабочего дня. Если залить слишком много кода, то у ревьюеров очень быстро замылится глаз — и многие проблемы будут просто пропускаться. Кстати, сюда же можно отнести и дополнительное требование — убирайте весь информационный шум, который мешает ревьюерам сосредоточиться на фактическом смысле изменений.
Self review
Большую часть фактических ошибок в своем коде автор способен увидеть сам. Поэтому перед тем, как подключать к ревью своих коллег, стоит самостоятельно один или два раза внимательно просмотреть свой код. Эта несложная процедура поможет очень сильно сэкономить время и нервы и улучшить отношения с коллегами.
Описание review
Когда проводишь code review на постоянной основе, сложно фокусироваться на фактическом смысле изменений — об этом я уже упоминал. Еще один способ помочь ревьюерам удерживать фокус — детально описывать смысл изменений. Обычно я работаю по следующему шаблону:
Чек-листы и их автоматизация
Чек-листы — это круто. Используйте их и для code review. Примеры вопросов из такого чек-листа: «Есть ли закомментированный код?», «Покрыта ли бизнес-логика тестами?», «Обрабатываются ли все ошибки?», «Вынесены ли строчки в константы?». Запоминайте все вопросы, которые часто возникают у команды на review, и заносите их в список.
Главное — не давать этому чек-листу разрастаться. Думайте о способах автоматизации каждой из перечисленных там проверок — если приложить достаточно усилий, большую часть потребностей вы сможете закрыть. Есть огромное количество инструментов, которые могут помочь в этой работе — линтеры, статические анализаторы, детекторы дублирующегося кода.
Измерение эффективности Code Review
Внедрение любого процесса должно сопровождаться сбором метрик его эффективности и их дальнейшим анализом. Сам процесс — не самоцель. Code review — не исключение, важно уметь понять, насколько сильно он помогает команде в ее работе.
Удобный вариант — исходить из целей, которых мы хотим достичь при внедрении code review. В качестве шпаргалки можно использовать те, которые я обозначил в первом разделе. Один из способов измерения эффективности достижения таких целей — использование подхода Goal-Question-Metric. Состоит он из трех этапов — определение цели, которую мы хотим измерить, постановка вопросов, которые помогут понять уровень достижения цели, и определение метрик, которые помогают ответить на поставленные вопросы. Разберем на примере.
Сначала нужно определить намеченную цель. Как пример — «Повысить уровень переиспользования кода». Можно и даже нужно использовать сразу нескольких целей — и измерять их независимо друг от друга.
Затем сформулируем вопросы, на которые нужно ответить, чтобы понять, достигаем ли мы цели. В нашем случае это «Используем ли мы общие библиотеки в проекте?», «Вынесены ли визуальные стили в отдельный компонент?», «Много ли кода дублируется?».
Ну и последнее — определение метрик, которые помогут ответить на вопрос. В нашем случае это количество общих библиотек, количество мест, где остались захардкоженные стили, уровень дублирования кода.
Использовать фреймворк довольно просто. Измеряем обозначенные метрики до внедрения процесса, определяем желаемый результат, и периодически, раз в месяц или в квартал, повторяем эти измерения. Если их можно автоматизировать — еще круче. Спустя какое-то время анализируем результат и определяем, достаточно ли изменились метрики, чтобы счесть процесс эффективным.
Почему эта метрика действительно хороша? Представьте, что большую часть времени разработчики занимались не предложениями по переиспользованию кода, а холиварами на тему пробелов или табов — с такими ревью эти ключевые показатели не сильно бы выросли, нужного результата мы бы не достигли и поняли бы, что что-то с процессом не то.
Кроме того, полезно собирать еще некоторые метрики, которые могут подсказать, с какими проблемами при использовании процесса мы столкнулись.
Если собирать такие данные по каждому ревью, то можно вполне адекватно оценить уровень вовлеченности в процесс у каждого участника команды. Ряд систем для проведения code review автоматически собирает такие данные — например, Crucible от Atlassian.
Заключение
Как я уже упоминал во введении, эта статья — краткая выжимка моего выступления, в котором я затрагиваю еще и различные инструменты для автоматизации процесса, правила и нормы поведения в команде и прочие аспекты проведения code review. Чтобы не пропустить появление записи — подписывайтесь на мой Telegram-канал, куда я обязательно выложу его по готовности. Если у вас остались вопросы — приходите на наш митап в субботу, 17 июня, и обсудим их в неформальной обстановке.
Code review: вы делаете это неправильно
Сегодня очень многие в разработке используют ревью кода. Практика полезная, нужная. Даже если вы не делаете ревью, вы наверняка знаете, что это такое.
На рынке есть куча инструментов для ревью кода с готовыми сценариями использования, рекомендациями и правилами. GitHub, Phabricator, FishEye/ Crucible, GitLab, Bitbucket, Upsource — список можно долго продолжать. Мы в Badoo тоже в своё время с ними работали: в своей предыдущей статье я рассказывал нашу историю ревью кода и о том, как мы пришли к изобретению собственного «велосипеда» — решения Codeisok.
Информации предостаточно, можно нагуглить кучу статей про ревью кода с реальными примерами, практиками, подходами, рассказывающих о том, как хорошо, как плохо, как нужно делать, а как — не нужно, что стоит учитывать, а что — нет, и т. д. В общем, тема «обсосана до косточек».
Именно поэтому другую часть айсберга можно и не заметить.
Я надеюсь, что вы серьёзно отнесётесь к тем вещам, которые я опишу в этой статье, в некоторых случаях специально утрируя. Ревью, как и любой другой процесс, требует внимательного и обдуманного внедрения, тогда как подход «Сделаем как у всех, лишь бы было» может не только не сработать, но даже навредить.
После прочтения этого вступления у вас может возникнуть вопрос: а что сложного в ревью кода? Дело-то плёвое. Тем более что большинство инструментов, перечисленных выше, сразу и флоу ревью предлагают (из коробки: поставил, закоммитил/ запушил — и вперёд!).
Но практика показывает, что всё не так очевидно, как кажется на первый взгляд. В том числе из-за мнимой простоты процесса. Когда всё налажено и работает, есть риск, что менеджер успокоится и перестанет погружаться в процесс, передав его разработчикам. А они или будут следовать процессу, или займутся чем-то другим в ущерб решению проблем, которые процесс ревью призван решать. Менеджер может и не догадываться, что что-то идёт не так, потому что не даёт установок или не навязывает правила. В то время как для бизнеса очень важно решать задачи как можно быстрее, не тратя время на незапланированные активности.
Когда-то давным-давно, когда я работал в другой компании, мне в память глубоко запала беседа о ревью кода с одним из ведущих разработчиков. Это был p1lot. Возможно, кто-то из читателей знаком с ним (p1lot, привет :)). Сейчас он работает с нами в Badoo, и это здорово.
Так вот, PILOT тогда сказал: «Самое сложное для меня в процессе ревью — пойти на компромисс и пропустить готовую и корректно работающую задачу дальше, даже если я знаю другой способ её решения и даже если мой способ мне нравится больше». На мой взгляд, эта мысль является ключевой. И основной посыл всей моей статьи так или иначе вертится вокруг этого постулата.
Зачем нужен процесс ревью кода?
У вас в компании есть ревью? Правильно ли вы его делаете? У меня есть тест, который, возможно, заставит вас усомниться в этом.
Нужно ответить всего на три вопроса:
Если вы не знаете, сколько времени потребуется на ревью, и не минимизируете его постоянно, то как вы осуществляете планирование? Возможна ли ситуация, когда исполнитель, который делал ревью четыре часа, не пил чай половину этого времени? Можно ли быть уверенным в том, что от задачи к задаче время на чаепитие не увеличивается? А, может, ревьюер вообще не смотрит код, а просто нажимает «Code is OK»?
И, даже если ревью делается добросовестно, как добиться того, чтобы с ростом кодовой базы и компании время на реализацию задач не увеличивалось? Ведь руководство, как правило, ожидает, что процессы будут ускоряться, а не замедляться.
Если же ответ на третий вопрос сразу не приходит в голову, то есть смысл задаться ещё одним. Знаете ли вы, зачем вам на самом деле нужен этот процесс? Потому что «так принято у всех больших ребят»? Может быть, он вам и не нужен вовсе?
Если вы спросите своих лидов и разработчиков о том, что представляет из себя «правильное» ревью кода, вы очень удивитесь тому, насколько разные вещи услышите. Ответы могут варьироваться в зависимости от личного опыта, убеждений, собственной уверенности в правильности или неправильности вещей и даже от используемого технологического стека и языка разработки.
Помните про готовые инструменты для ревью кода, предлагающие свои подходы и флоу? Мне, например, интересно, как бы ответили на вопрос разработчики этих инструментов. Будут ли коррелировать их ответы о «правильности» ревью с ответами ваших сотрудников? Не уверен. Иногда я грустно наблюдаю, как кто-то внедряет у себя инструменты ревью, ни на минуту не сомневаясь, что они необходимы. То ли люди делают это «для галочки», то ли чтобы отчитаться, что «ревью кода внедрили, всё хорошо». И в итоге забывают про это.
Не хочу быть Кэпом, но тем не менее. Общаясь с сотрудниками, обращайте внимание на ответы вроде «Потому что так заведено» или «Это же best practice, все так делают». Вы и сами отлично знаете, что не нужно бездумно внедрять какой-то процесс, не понимая, зачем он нужен. Любой процесс должен быть оправдан и внедрён (если необходимо) с поправкой на нужды бизнеса и проекта, а также на проблемы, которые действительно существуют и которые действительно хочется решить. Карго-культу в компании с хорошей инженерной культурой не место.
Соответственно, менеджеру важно донести до людей то «правильное» ревью кода, которое необходимо именно в его проекте. А перед этим, разумеется, стоит критерии «правильности» сформулировать для себя, выбрать подходящие инструменты и установить уместные правила. А там уже и до контроля недалеко.
Плохое ревью кода
Так какой он, тот самый правильный процесс? Давайте разбираться. Ниже будет много моих личных рассуждений, и тем, кому не терпится узнать, к чему я всё это пишу, предлагаю сразу перейти к части «Хорошее ревью кода».
Тем же, кто остался, говорю спасибо и тем не менее предлагаю определить правильность ревью самостоятельно, исходя из нужд вашего проекта, тщательно всё обдумав. А я лишь попробую вам в этом помочь.
Чтобы выделить для себя важные и необходимые вещи в любом процессе, бывает полезно для начала отсечь очевидно ненужные, которые вредят инженерной культуре. Так и поступим.
Обмен знаниями
На вопрос «Зачем нужен процесс ревью кода?» я очень много раз слышал ответ «Для обмена знаниями». Действительно, полезная и нужная вещь. И многие согласны с тем, что важно иметь в команде процесс для обмена знаниями и экспертизой. Но уверены ли вы в том, что ревью кода подходит для этого?
Я не раз спрашивал людей, что они имеют в виду под «обменом знаниями». И в ответ слышал разное.
Во-первых, это демонстрация новичкам (в команде или затронутом компоненте) принятых правил и практик: вот так у нас принято делать, а так мы не делаем, потому-то и потому-то.
Во-вторых, это свежий взгляд новичка (опять же в команде либо затронутом компоненте) на то, как делаются обычные вещи. Вдруг они делаются неэффективно, и новый человек поможет это обнаружить?
В-третьих, это просто ознакомление с некоторой частью кода. Ведь если в будущем ревьюер столкнётся с необходимостью изменять эту часть кода, ему будет намного легче.
Давайте пройдёмся по всем пунктам и попробуем оценить, насколько они уместны в процессе ревью.
Code review как инструмент обучения новичков
В данном случае речь идёт в основном о таком сценарии: новичку даётся задание, он его выполняет, а потом опытный член команды (владелец компонента) указывает на ошибки, которые он допустил. Процесс важный и нужный, не спорю — новичкам нужно как-то показывать принятые в команде правила.
Но давайте начистоту: не поздновато ли? Не будет ли более правильным рассказать новичку об этих правилах до допуска его к коду? Ведь цена ошибки очень высока — редко новички сразу работают так, как вам нужно. А значит, задача будет возвращаться и возвращаться на доработку. А значит, продукт станет доступен пользователю позже, чем мог бы.
Получается, в процесс, продолжительность которого трудно оценить, мы добавляем ещё один, временные затраты на который ещё менее предсказуемы. Таким образом мы увеличиваем время, необходимое на доставку задачи пользователю, на ещё более неизвестную величину.
Разумеется, иногда обучение новичков через рабочие процессы имеет право на существование. Но порой мы не задумываемся о недостатках подходов, которые вошли в привычку. А допустить ошибку тут не просто легко, а очень легко.
Например, если в компании нет отлаженного процесса обучения и коучинга, менеджер вынужден «бросить в воду» новичка. У последнего при этом не остаётся выбора: нужно либо «плыть», либо уходить из компании. Кто-то реально учится на таких ситуациях, а кто-то не выдерживает. Думаю, многие сталкивались с подобным на протяжении своего профессионального пути. Мой же посыл в том, что драгоценнейшее время может тратиться неоптимально из-за такого явления. Равно как и процесс адаптации нового сотрудника в команде может выполняться неоптимально. Просто потому, что ни у кого руки не дошли организовать эффективный процесс внедрения новых сотрудников в команду, и менеджер подумал, что новичок всему научится на этапе ревью кода. А на самом деле это два разных процесса, очень нужных и важных.
Конечно, даже при условиях, что правила изначально объяснены новичку и что в компании существуют другие процессы обучения, процесс адаптации новичка нужно как-то контролировать. Ревью — это один из процессов, который может помочь. Но контроль и обучение — это разные вещи, не так ли? Тем более что в контроле нуждаются все члены команды, а не только новички. Ведь все мы можем делать ошибки, забывать о договорённостях и так или иначе влияем на ту часть системы, которой владеет вся команда (в данном случае на код).
Какой можно сделать вывод? Описанный выше процесс направлен на достижение иной цели: не на обучение, а на контроль. И этот самый контроль необходим не только новичкам, а команде в целом.
Всё это легко формулируется в такой тезис: «Ревью кода необходимо, чтобы контролировать соблюдение договорённостей и общих правил всеми членами команды«. А обучение новичков в этом случае будет не чем иным, как искусственной подменой цели, которая только запутает людей и направит процесс в другое русло.
Но даже с этим выводом, который, казалось бы, сформулирован правильно, можно наломать дров. Ревью кода — это этап, который наступает тогда, когда код уже написан. И может случиться так, что код, написанный без соблюдения общих правил, подгонять под общее лекало будет очень дорого. Наша задача состоит в том, чтобы сообщить исполнителю о том, что что-то пошло не так, как можно раньше. И поэтому я утверждаю, что иногда ревью кода — не самый подходящий процесс для контроля соблюдения общих правил. Во многих случаях проверки на соответствие правилам можно и нужно перенести на более ранние этапы.
Например, можно проверять форматирование кода в хуках системы контроля версий (равно как и использование задепрекейченных классов, договорённости о расположении файлов в соответствующих папках, использование внешних зависимостей и сторонних библиотек и др.). Таким образом минимизируется время, необходимое на ревью кода.
Продолжая разговор об обучении новичков в процессе ревью кода, проведём аналогию. Допустим, вы производите какой-то товар, например, торты. Допустим, вы получили заказ на торт для свадьбы VIP-персоны. Доверите ли вы «ревью» готового торта новичку? Готовы ли вы к тому, что новый кондитер возьмёт на себя ответственность за позор или успех всей пекарни на этой свадьбе? А может, вы хотите, чтобы он на этом этапе познакомился с правилами, принятыми в команде (как выпекать коржи, готовить крем и настаивать клюкву на коньяке)? Очевидно, что и процесс знакомства новичка с правилами, и контроль с его стороны — довольно странные вещи на данном этапе: торт-то уже испечён. Так почему же с фичами и кодом мы можем поступать по-другому? Или фичи, которые мы запускаем, не несут за собой позор или успех нашей команды в глазах пользователей и заказчиков?
Вы можете возразить, сказав, что задачи «для важных персон» мы готовим не каждый день и что новичку вполне можно доверить не очень срочную или не очень важную задачу. И будете правы.
Но во-первых, чему новичок научится на пустяковых задачах, в которых мало изменений кода (и эти изменения не в критичных местах и для бизнеса наверняка не столь важны, раз задача несрочная)? Как он может научиться печь торты, если всё время взбивает сливки? Переход от простого к сложному, конечно, нужен. Но делать это необходимо, тщательно контролируя процесс. Новичков нужно учить, а не бросать учиться самостоятельно.
А во-вторых, компании даже такой, казалось бы, полезный и правильный подход может навредить. Понять это очень просто, используя метод доведения до абсурда, чтобы сделать вывод максимально простым и понятным.
Представим, что мы открыто заявляем, что задачи, которые нам даёт продакт-менеджер, нужны для обучения новичков. Почему? А так же, как с ревью кода: мы ведь поручаем некоторые простые и несрочные задачи новичкам, чтобы они научились работать так, как у нас принято.
К чему это может привести в итоге? Ретивый исполнитель, который добросовестно делает своё дело и считает, что всё, что он делает, должно быть сделано максимально хорошо, примется за процесс обучения. Он может поставить задачу сделать несколько реализаций вместо одной, чтобы потом показать обучаемому недостатки и преимущества разных подходов. Он может читать лекции, сравнивая подходы и best practices, применяемые в компании и за ее пределами. Он может много чего ещё предпринять, чтобы обучить новичка. В результате время, требуемое на реализацию задачи, будет всё увеличиваться, ведь вместо разработки мы фокусируемся на обучении.
В случае ревью кода такой ретивый сотрудник инициирует длинную дискуссию в комментариях к ревью о пользе и вреде тех или иных реализаций, постит куски кода со Stack Overflow, показывая, что в других головах бывают другие идеи, даёт ссылки на статьи и книги, которые обучаемый должен прочитать, чтобы понять, что его реализация неидеальна.
Это нормальный процесс обучения, который может существовать, но который должен делаться правильно. И далеко не всегда стоит интегрировать его в процесс решения задачи бизнеса. Потому что это два разных процесса. Пусть новичок делает разные составляющие торта, пусть сделает несколько вариантов, пусть что-то испортит и выбросит. Пусть кто-то более опытный показывает ему, как нужно действовать и пересказывает старинные рецепты. Но учиться «на боевом конвейере», который производит ваш товар для клиентов — не лучшая идея. И если уж вы решились на такое, то «водите за ручку» новичка, не позволяя ему создавать помехи производственному процессу в ходе своего обучения.
Если ваша компания — это не институт, не школа, не техникум и не какое-либо другое образовательное учреждение, то обучение — не ваша прямая обязанность. Бизнес нанял вас для решения других задач и достижениях других результатов.
К слову, именно поэтому мы не добавляем в Codeisok функционал для загрузки картинок, оформления текста, подсветки кода в комментариях, хотя запросов на подобные фичи поступало и продолжает поступать немало. Мы пропагандируем идею того, что ревью кода — это не личный блог, не мессенджер и не сервис для обучения. Инструмент нужен для другого. Ведь для указания на недостатки кода обычного текстового комментария более чем достаточно.
Code review как свежий взгляд на код
Идём дальше. Следующий сценарий «обмена опытом» такой: мы в команде что-то делаем, соблюдая внутренние договорённости, и у нас замылился глаз, а тут пришёл новый человек (из другой компании или из другого компонента) — и, возможно, он увидит недостатки в нашей организации работы.
Идея хорошая, звучит разумно. Действительно, а вдруг мы делаем что-то не так?
Но опять вернёмся к сроку жизни задачи и наступлению этапа ревью кода. Не поздновато ли? Торт уже испечён, коржи смазаны кремом, розочки приклеены. Цена ошибки очень высока. И тут мы узнаём, что в другой пекарне в коржи добавляют соду, гашенную лимонным соком, для пышности. И что? Что делать? Переделывать?
Очевидно нет, так как: 1) мы всегда делали без соды, и результат был неплохим; 2) возможно, покупатели берут торты именно у нас, а не в другой пекарне, потому что им не нравится привкус соды; 3) торт уже готов, свадьба сегодня вечером, а новый торт испечь мы не успеем.
Тогда зачем это всё? Делиться опытом надо. Свежий взгляд нужен. Но, как мне кажется, на другом этапе. Например, перед тем как печь коржи, можно уточнить у новичка: «А как вы делали это раньше? А почему этот способ лучше?» И, наверное, стоит испечь пару тортов по-старому и по-новому, чтобы дать нашим постоянным клиентам попробовать и узнать их мнение.
Бездумное внедрение best practices, увиденных в статьях или докладах, может нанести вред компании и продукту. «Соду добавляют в коржи все крупные игроки: „Бугл“, „Трейсбук“, „Райл.ру“, „Юмдекс“. Все так делают». И что? Из-за этого Петя должен немедленно взяться за переделку задачи, которая уже готова?
Я уверен, что нет. Если изначально, перед решением задачи, вы не договаривались, что «в коржах будет сода», то очень недальновидно требовать её добавления на этапе ревью кода. У вашего бизнеса нет цели «иметь соду в коржах». Если ваши торты и так неплохо продаются, то совершенно неважно, есть в них сода или нет.
Нужно понимать, что обмен опытом — это другой процесс, никак не завязанный на ревью кода. Он может происходить раньше, позже или параллельно с ним, но он — другой. Можно устраивать взаимные мастер-классы с конкурентами. Некоторые пытаются выкрасть суперсекретный рецепт и суперсовременную методику взбивания крема перфоратором. Кто-то старается подсмотреть чужие идеи и усовершенствовать с их помощью свои процессы. Но странно делать это на работающем конвейере, на том этапе, когда ваш товар уже практически готов, а цена переделки очень высока.
Ведь мы говорим об этапе ревью. Ревью кода, который уже написан и готов к переходу на следующий этап. Этот код ждёт нажатия ревьюером кнопки «Code is OK». И ваши заказчики совсем не готовы к тому, что вы будете препарировать испечённый торт с новым поваром, чтобы показать ему, как вы печёте торты и выслушать его критические замечания.
Code review как знакомство с частью кода
Пожалуй, это выглядит как самая разумная и понятная часть, с которой многие согласны. Сценарий тут подразумевается такой: один программист написал код задачи, остальные на него посмотрели, изучили — и теперь знают, как с ним работать. Таким образом мы уменьшаем риск возникновения bus factor: если разработчик уйдёт, другие смогут успешно работать с его кодом. А также мы готовы к тому, что в следующий раз этот код может «потрогать» кто-то другой, и в этом случае он уже будет знать, как с ним работать.
Давайте подумаем, действительно ли это работает так, как задумано, и действительно ли помогает людям обмениваться компетенциями и знаниями о конкретных участках кода.
Посмотрим на ситуацию глазами того, кто написал код. В каждой ли задаче он применяет подходы и практики, которые обязательно должны усвоить все участники команды?
Допустим, он изобрёл какой-то крутой алгоритм сортировки (может, давно уже изобрёл и постоянно использует, а может быть, только что). Нужно ли, чтобы об этом знали все члены команды? Конечно, да. Нужно, чтобы люди узнали, что крутой программист Вася создал нереально быстрый и эффективный алгоритм сортировки, который будет полезен всем.
Однако, на мой взгляд, таких крутых вещей, которые непременно должны интегрироваться в общие правила и стандарты, не так уж много. И используются они далеко не в каждой задаче. Так стоит ли каждый раз останавливать весь конвейер, отрывать всех от работы и показывать им код всех задач Васи?
Очевидно, что во многих компаниях вся команда узнать о ноу-хау Васи на этапе ревью не может. Ведь ревью делает не вся команда, а какое-то количество ревьюеров. Если у вас это делают все, рано радоваться: с ростом команды это будет всё более и более неудобным, а в конечном итоге и невозможным. Этот процесс не масштабируется, и важно помнить, что временные ресурсы, которые можно тратить на ревью кода, ограниченны.
Теперь посмотрим на ситуацию со стороны других разработчиков, которые могли бы сделать ревью кода Васи и оценить его труд. Сидят ли они на своих местах без дела и ждут ли, пока Вася им покажет что-нибудь крутое в коде? Наверняка нет — они работают над своими задачами. У всех есть свои дела, и разработчик не всегда готов всё бросить и моментально переключиться на обсуждение достижений коллег, какими бы ошеломляющими они ни были.
И, наверное, разумно было бы, если бы Вася сообщил о своём изобретении всем как-то иначе. Сделал презентацию, например. Или просто написал письмо с куском кода и объяснениями, почему это круто, почему его алгоритм реально классный и почему он теперь должен стать стандартом для всех. Остальные его прочитают, каждый в своё время, зададут вопросы, согласятся или не согласятся с решением. И только после этого можно принимать или не принимать новый стандарт. Возможно, у кого-то окажется предложение лучше: более оптимальное, дешёвое, быстрее реализуемое.
Чувствуете? То, что я описываю, это не процесс ревью кода — это процесс создания и одобрения общих практик и подходов. Совершенно иной процесс.
И на этом этапе снова могут всплыть best practices от коллег и «В моей прошлой компании это делали по-другому» или «Я читал, что это делают иначе». И что? Best practices в общем случае, для сферической компании в вакууме, могут быть подходящими. Означает ли это, что все они будут полезны в вашей компании? Как минимум не всегда. И уж точно это не значит, что кто-то должен немедленно переписать свой код, на написание которого уже потрачено время.
Соответствие любым абстрактным или внешним best practices, гайдлайнам, модным тенденциям и т. д. — каким-то правилам, которые оторваны от компании/ контекста — ради самого соответствия никому не нужно. «Статические методы считаются плохим тоном», «Такое теперь надо выносить в трейты», «Синглтон — плохая практика, лучше использовать фабрику и DI». Кому надо? Кем считается?
Порой можно услышать здравые аргументы, но справедливые для абстрактных проектов и задач, а не для реальных. Даже полезные и нужные вещи обсуждать и рекомендовать на этапе, когда код уже написан, — поздно, потому что внедрение обойдётся неоправданно дорого.
Кроме того, в коде Васи может быть не новый крутой алгоритм или ноу-хау, а «костыль», грязный хак, который ему пришлось использовать по каким-то причинам. Действительно ли об этом должны знать все в команде? Если грязный хак оправдан и по-другому сделать было нельзя, то, наверное, да. Но даже в этом случае не стоит отвлекать всю команду, останавливая конвейер. Сомневаюсь, что и самому Васе эта идея понравилась бы.
Во-первых, мало кто готов «прямо сейчас» отвлечься и оценить «грязность» хака, ведь все заняты своими задачами. А во-вторых, никто ничего не запомнит. Да и люди в команде меняются, и, если кто-то в будущем наткнётся на этот хак, у человека так или иначе возникнет вопрос: почему сделано именно так? И оптимальным решением будет добавление комментария прямо в код. Комментария, объясняющего причину, которая вынудила прибегнуть к такому хаку (вспоминаем правила хорошего тона при комментировании кода: мы описываем в комментариях не что мы делаем в коде, а почему мы делаем именно так).
А если можно избежать использования этого грязного хака, то очевидно, что задачу стоит переоткрыть и заставить Васю переделать. Это прямое назначение ревью кода, и понятно, что к ознакомлению всей команды с кодом оно отношения не имеет (зачем всем знать о коде, который всё равно будет переписан?).
Третий случай — это когда в задаче ничего супернового и грязных хаков нет. Она базируется на всех принципах и правилах, принятых в команде, оформлена в соответствии с общими стандартами и т. д. Так зачем же тогда на неё отвлекаться всей команде? Ведь никакого bus factor нет, и, если кому-то другому придётся работать с этим участком кода в будущем, он без труда в нём разберётся.
Ну и, наконец, если мне всё ещё не удалось вас убедить, то у меня вопрос: как понять, что обмен знаниями в процессе ревью произошёл?
— Петя, ты прочёл код, который написал Вася?
— Прочёл.
— Всё понял?
— Всё понял.
Вот и весь процесс верификации. А где уверенность в том, что Петя всё понял правильно? Где уверенность в том, что, когда Петя в будущем будет изменять этот участок кода, он не наломает дров? Как измерить время, необходимое для погружения в задачу для разработчиков, один из которых код ранее не видел, а другой — пару раз делал ревью этого кода?
Более того, где уверенность в том, что в следующий раз работать с этим участком кода будет именно Петя, который делал ревью, а не Эдуард, который сейчас делает ревью задачи Арсения с совсем другим компонентом?
Таким образом, я утверждаю, что ознакомление с кодом чужих компонентов в процессе ревью кода работает далеко не так, как ожидается. Это только замедляет этап ревью кода и, как следствие, тормозит доставку фичи пользователю.
Если необходимо делиться знаниями между разными компонентами, то лучше подойти к этой задаче как к отдельной и самостоятельной. Следовать общим правилам для всей компании, использовать одинаковый технологический стек, делиться знаниями на внутренних митапах и семинарах, писать общую документацию (опять же по принятым стандартам и правилам), передавать задачи по соответствующим компонентам на реализацию коллегам из других компонентов, соблюдая все правила по адаптации новичков (рассказать о том, как принято в компании, что вы делаете, а что — нет, помочь составить хороший технический план и т. д.). Такое погружение в компонент гораздо полезнее для всех участников, нежели просто просмотр кода.
Ревью кода — это процесс верификации, контроля, процесс, который должен проходить максимально быстро. И примешивать к нему другие процессы (обучение новичков, обмен знаниями, демонстрация крутизны экспертизы и т. д.) просто неуместно. Это как минимум неоправданно дорого и — главное — не работает на данном этапе.
Code review как документация
Ещё один вариант ответа на вопрос «Зачем нужно ревью кода?» был про документирование. Тут может быть не совсем очевидно, что имеется в виду, поэтому поясню.
Сценарий подразумевается такой: разработчик и ревьюер кода о чём-то договорились в комментариях к ревью, и в будущем, если у кого-то возникнет вопрос о том, почему в данном месте сделано именно так, информацию об этом можно будет найти в ревью. То есть по git blame найти коммит, по коммиту найти тикет, по тикету найти ревью, в ревью найти обсуждение, изучить его и понять, почему сделано именно так.
Получается, что разработчик, у которого и так много источников информации — стандарты и соглашения, техническое задание, тикет в багтрекере, сам код (с комментариями или без) — должен лезть ещё в один. И читать весь тред, пытаясь уловить нить беседы и понять причины, побудившие сделать именно так. Причём мнения сторон в этом треде могут измениться несколько раз. Звучит странно, не правда ли?
Но вопросы действительно могут возникнуть. Что делать в этом случае?
Очевидно, что, если вопрос возник на этапе ревью, на него следует ответить. Но также нужно понимать, что если у ревьюера возник вопрос, то такой же вопрос может возникнуть и у людей, которые будут работать с кодом позже. Это может быть знаком того, что код написан в обход каких-то соглашений (и требуется пояснение, почему). В этом случае стоит оставить пояснение прямо в коде, например, в виде комментария со ссылкой на тикет — тогда любой человек, глядя на код, будет понимать, почему сделано именно так.
Если причин для игнорирования соглашений нет, то очевидно, что задачу необходимо вернуть на доработку и привести к требуемому виду. Стоит ли хранить для этого историю переписки и заставлять разработчиков в будущем всю эту историю перечитывать? Думаю, это лишнее.
Кроме того, может быть так, что код написан недостаточно понятно для ревьюера, хоть и соответствует правилам. В этом случае его следует переписать, чтобы для ревьера и будущих разработчиков он стал понятен. Опять же, нужно ли это хранить в истории для будущих поколений? Я в этом не уверен.
Даже если возникла ситуация, когда комментарии нужны и будущим поколениям стоит о них знать, в этом случае лучше оставлять их в коде или тикете — в тех источниках информации, которые у разработчика уже есть. Зачем вводить новый (тем более со всей историей переписки)?
В тикете можно написать «Решили сделать так-то по таким-то причинам» как итог всех обсуждений. Так и читать понадобится меньше, и много времени у интересующегося разработчика не отнимет. Ну и информацию при необходимости разработчик сможет получить.
Вывод напрашивается сам собой: использовать ревью кода как источник документации не стоит. Этот процесс нужен для другого.
Хорошее ревью кода
Список ошибочных вещей и процессов, которые люди имеют склонность добавлять в ревью кода, можно долго продолжать. И даже если бы я поставил перед собой цель собрать полный список, я бы не смог сделать его исчерпывающим. Ведь сколько людей, столько и мнений.
Я думаю, что в данном случае нужно иметь в виду тот факт, что смешивать несколько процессов в один — не всегда правильно. Особенно если речь идёт о процессах, продолжительность которых сложно планировать и контролировать.
Правильный процесс ревью кода — это процесс контроля. Контроля того, что задача выполнена в полном объёме. Контроля того, что соблюдены общие правила и договорённости. Контроля того, что решение не избыточно и что его легко поддерживать и развивать в будущем.
Следовательно, я бы выделил следующие моменты, которые обязательно должны быть проконтролированы на этапе ревью:
Архитектура и дизайн решения
Насколько предлагаемое решение соответствует задаче? Насколько оно сложно для понимания, поддержки, расширения? Насколько получившаяся архитектура требовательна к ресурсам и какова сложность реализованных алгоритмов? Можно ли было сделать проще, понятнее, дешевле? Сделано ли что-то лишнее, что не относится к задаче? Используем ли мы внешние зависимости и библиотеки? Насколько это оправданно? И так далее.
Не забываем, что это этап контроля. Соответственно, архитектура решения должна быть оговорена заранее. На данном этапе мы должны удостовериться, что договорённости соблюдены.
Также стоит иметь в виду, что это один из самых сложных, ответственных и трудоёмких моментов в ревью кода. Человек, выступающий в роли ревьюера, должен быть готов идти на компромиссы и помнить о том, что идеальных решений не бывает. И если он видит в задаче решение, которое по тем или иным причинам считает неидеальным, то он должен в первую очередь примерить его на нужды бизнеса, а не на свой перфекционизм.
Ревьюер может предложить свою реализацию, которую он считает более правильной с точки зрения best practices, паттернов и других вещей. Но тут очень важно понимать, что решение, которое он видит в коде, лучше его собственного уже одним лишь тем, что оно готово. Оно уже написано. Разработчик потратил своё время на реализацию, интеграцию этого куска кода с другими элементами, тестирование и написание автотестов и так далее. И исправлять код следует только в том случае, если решение заведомо неправильное.
Соблюдение правил и соглашений, принятых в команде
Все мы разные. У каждого свой взгляд на вещи, и зачастую можно обнаружить, что даже в слаженном и давно сработавшемся коллективе взгляды могут быть диаметрально противоположные. Кто-то считает, что табуляции лучше пробелов, а кто-то уверен в обратном.
Чтобы это не сказывалось на ежедневных задачах, чтобы любой участник команды мог как можно быстрее вникнуть в код и задачу другого, устанавливают командные соглашения. Начиная со стандартов оформления кода, структуры папок и файлов проекта и заканчивая формализацией API-методов и запретами на использование тех или иных конструкций языка. Таким образом обеспечивается и поддерживаемость кода, и уменьшение риска возникновения bus factor, и много что ещё.
Тут опять же важно помнить о том, что на этапе ревью мы контролируем соблюдение общих договорённостей. Учить на этом этапе стандартам кодирования уже поздно и может быть неоправданно дорого.
Корректность решения
Имеет ли решение какие-то недостатки? Опечатки в коде, магические числа и другие неопределённые константы. Магические строки и другие неожиданные данные, которые программист не учёл при решении задачи. Проверки на null и другие места, где потенциально можно «выстрелить себе в ногу». Проверка решения с точки зрения информационной безопасности и так далее.
Это очень важная часть ревью кода, и выполняться она должна очень тщательно и аккуратно. Сколько программистов у вас в команде знает, что это необходимо делать на этапе ревью? Сколько программистов это реально делает?
Тестируемость кода и наличие юнит-тестов
Данный этап проверок также очень важен, ведь он направлен на улучшение той самой пресловутой поддерживаемости кода.
Многие понимают, что означает термин code maintainability, но далеко не все могут объяснить, что это такое. А раз так, то как тогда ставить задачу команде на поддержание этой самой maintainability? Поэтому я считаю, что разработчик, подумавший о том, как его код будет тестироваться, а уж тем более тестирующий собственный код и написавший автотест для автоматизации тестирования, естественным образом будет стремиться к тому, чтобы его код удовлетворял большинству критериев code maintainability. Ведь без этого написать автотест практически невозможно.
Общей рекомендацией к любому изменению кода также может быть правильная декомпозиция задач. Чем меньше объём кода, проходящего через конвейер всех процессов от идеи до продакшена, тем легче этот код проверять на соответствия, тестировать, объединять с кодом других задач и выкладывать. Ревью кода — не исключение. Задачу с большим количеством изменённых строк во многих файлах очень тяжело читать и понимать (и удерживать в голове зависимости). Риск и цена исправления недочётов могут быть очень высокими.
Заключение
Вот, собственно, и всё. Эти четыре момента — это именно те самые вещи, которые необходимо проверять на этапе ревью. Их легко формализовать, легко донести до исполнителей, а значит, несложно и сформулировать критерии верификации и прогнозировать продолжительность. Автоматизация и другие способы минимизировать время ревью становятся более чем возможными.
И напоследок дам ещё несколько советов.
Важно помнить, что любой возврат кода на доработку не лучшим образом сказывается на качестве реализации. Даже если все действуют из лучших побуждений. В случае ревью кода это работает так: разработчик правит код, но тестирует его уже не так тщательно, как в первой итерации (зачем? Ведь он уже всё проверил, а изменил совсем чуть-чуть). Опыт показывает, что большинство таких ситуаций оборачивается багами именно в тех местах, где были правки по результатам ревью кода. Так работает человеческая психология.
В начале статьи я предлагал вам ответить на три вопроса про необходимость и правильность ревью. Теперь у вас есть алгоритм, который поможет найти ответы. Зная шаги контроля и учитывая размер задачи, вполне можно планировать время, необходимое на ревью кода, каждый раз стремясь его всё больше и больше сократить.
Внедряя любой процесс, важно помнить о целях, которые мы перед собой ставим, и о проблемах, которые хотим решить. Тогда будет гораздо проще отделять зёрна от плевел и формулировать измеряемые критерии оценки эффективности. А формулировать их нужно для себя самого и для своей команды, которая тоже остро нуждается в решении возникших проблем, но понимать их может по-своему.
Есть и ещё один важный момент: те процессы, правила и ценности, которые справедливы для одной компании, могут быть не столь полезными и работающими в другой. То, что я описал как примеры правильного ревью, работает в нашей компании. Мы пропагандируем быструю разработку, частые релизы и делаем ревью для каждой задачи. Подумайте о том, насколько это применимо к вашему проекту, и о том, что ревью — это один из тех процессов, которые пускать на самотёк нельзя.