Внутренние правила разработки кода


Рано или поздно в любой команде разработчиков необходимо регламентировать правила разработки и регламентировать процессы. Мы решили собрать все наработанные правила в одной статье.

Самый крупный проект, который мы разработали - SmartVend, изначально у нас уже был сформированный подход к разработке IT-продуктов, но в маленьких проектах и небольшой команде все происходит достаточно тривиально: менеджер ставит задачи дизайнеру, front и back разработчикам, следит за ходом разработке и проблемы решаются по мере их поступления, но с ростом проекта необходимо менять подход.

Мы начали работу над проектом в ноябре 2017, ровно год назад на момент написания статьи. Изначально у нас был только аналог нашего продукта на основе которого мы создавали сервис. За год мы создали полноценный продукт, который уже пользуется спросом на рынке. В этом посте я хочу поделиться подходами к разработке, которые у нас сформировались за этот год.

У сервиса есть свои особенности. Основная наша задача - обрабатывать максимальное количество запросов от торговых автоматов в единицу времени, сохранять обработанные данные в базу и выдавать актуальные данные пользователю. Запросы клиентов на разработку кастомных фич поступают довольно часто и мы должны их реализовывать с максимально возможной скоростью. При этом мы должны держать качество продуктов на таком уровне, чтобы не уступать конкурентам и даже преуспевать в этом. Замечу, что высокая скорость доставки фич подразумевает в том числе поддержание достаточно высокого качества кода. Иначе продукт рано или поздно захлёбывается в багах.

Всё описанное ниже так или иначе выстрадано и основывается на собственном опыте и все кейсы взяты из реальной жизни.

Качество кода и архитектура

  • Мы минимизируем время доведения фичи до продакшна при сохранении приемлемого качества.
  • Любая задача предполагает два решения: быстрое и правильное. Для любой фичи мы продумываем оба варианта так, чтобы была возможность апгрейдить быстрое решение до правильного, делая минимум ненужной работы «на выброс». Выкатив быстрое решение, некоторое время смотрим и понимаем, нужно ли правильное.
  • Критично. Зачастую, разница по времени между тем, чтобы «решить первым попавшимся способом, забив костыль» и «решить красиво и аккуратно» – несколько часов. Поэтому мы всегда думаем, перед тем как писать.
  • Если есть выбор между минорной оптимизацией и читабельностью / архитектурой – выбираем второе. Две миллисекунды ничего не решат, а с этим кодом нам ещё жить и поддерживать.
  • Думаем о будущем. Ближайшее будущее при этом важнее отдалённых перспектив. Если решение можно сделать сложным (читай «долгим») и гибким, либо простым, но прибитым гвоздями, стоит прибивать гвоздями, а затем рефакторить по необходимости. Лучше потратить день на простое решение сейчас и месяц на возможный рефакторинг через год, чем две недели сейчас (да, именно это и называется техдолг). Важно, что такие решения стоит обсуждать с командой. В одиночку можно неверно оценить вероятность расширения этой фичи в ближайшее время.

Новые технологии

Новые технологии – это круто, давайте их использовать. Но наш продукт не испытательный полигон. Если хочется применить новый алгоритм или технологию, это можно сделать при выполнении следующих условий:

  • технология несёт ощутимый профит (оптимизация, качество архитектуры, кода, масштабируемость, и всё это действительно должно быть нужно, а не притянуто за уши);
  • технология нормально вписывается в текущий стек (не нужно писать часть сервисов на Java, если весь код написан на Node.js); технология не ухудшает качество архитектуры и читабельность кода (это субъективно, поэтому обсуждается с командой);
  • времени на реализацию и поддержку новой технологии (включая поиск новых разработчиков) уходит не больше, чем на работу в рамках текущей технологии. Опять же, всё зависит от ожидаемого профита и обсуждается с командой;
  • любая новая технология обсуждается с командой: если она классная, то правильно её использовать всем, если не очень, то групповое обсуждение позволяет быстрее это понять; vне надо самостоятельно реализовывать алгоритмы, уже реализованные в готовых библиотеках (кроме случая, когда это маленький кусок огромного фреймворка и не имеет смысла ради одного решения тащить его весь).
  • если вы сделали что-то крутое и удобное – поделитесь решением с командой.

Коммуникация

  • Обсуждаем решение вместе. Чем сложнее и критичнее функциональность, тем важнее такое обсуждение. Если решение кому-то не нравится – убеждаем друг друга до тех пор, пока не появится согласие. Или время обсуждения не превысит разумные сроки.
  • Если договориться не удалось – последнее слово за руководителем. У нас разумная демократия. При этом руководитель получает большой минус в карму и должен испытывать моральные страдания. И уж точно не использовать это право часто.
  • После того, как определились – делаем так, как договорились. Даже если был категорически не согласен. Никаких «Я лучше всех знаю, как делать сервис, поэтому сделаю то, что считаю нужным»
  • «Не в проде – не сделано». Каждый сам следит за своими задачами. Если фича готова к тестированию, нужно позаботиться, чтобы она выкатилась в тестинг. Если она готова к релизу – нужно позаботиться о том, чтобы она попала в прод как можно раньше. Люди, ответственные за формирование релиза, не всегда помнят про каждую фичу. Не стесняемся напоминать про неё.
  • Включать голову нужно обязательно. Если задача кажется странной, непонятной или слишком долгой, то об этом надо чётко и громко говорить. И делать это до тех пор, пока не сложится ясного понимания, почему всё должно быть именно так. Бывает, что правильные вопросы, заданные в нужный момент, экономят целые дни разработки.
  • Если задача не укладывается в разумные сроки, об этом надо громко говорить. Не стоит сидеть и несколько недель пилить задачу с оценкой в пять часов. Если она сильно затягивается, значит что-то идёт не так. Возможно, есть недопонимание в постановке или мы недооценили объём работы. В любом случае такие задачи надо повторно обсуждать (и в результате иногда откладывать или даже закапывать).
  • Появившиеся проблемы стоит решать самостоятельно. Но если понятно, что процесс затягивается, обязательно рассказывать о них и просить помощи у коллег. Залипать на несколько дней в состоянии «я должен сделать всё сам и не отвлекать товарищей» – это очень плохо.
  • Никто не смотрит, во сколько каждый из нас приходит и уходит до тех пор, пока мы всё успеваем, а наш режим не начинает мешать работе команды. Но сидеть ночами только из-за того, что не успеваете что-то сделать, не нужно. Если это превращается в привычку, значит проблема более глубокая – в планировании, переоценке собственных возможностей и т.д. Пока разработчик овертаймит по ночам (и в результате всё успевает), шансы на то, что эту проблему кто-то увидит и решит, сильно снижаются.
  • Бывает, что нам нужно обязательно запустить важную фичу к условленной дате (или просто как можно скорее). В этом случае мы выходим работать в овертайм. При этом руководитель получает большой минус в карму и должен испытывать моральные страдания. И уж точно не использовать эту возможность часто. Такие овертаймы компенсируются.

Смертные грехи

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

  • Работать, не включая голову: «мне сказали сделать – я сделал». Каждый член команды должен понимать суть фичи, которую он делает и её влияние на продукт.
  • Бросать не выкаченные в прод фичи со словами «я всё сделал». То, что мы делаем, должно работать в продакшне. Пока фича не в проде, она не готова.
  • Договориться делать одним способом, а потом тихо сделать по-своему. Выше уже было про «я лучше всех знаю, что лучше». Но лишний раз напомнить о том, что это плохо, не помешает.
  • Затягивать важные фичи, закапываясь в обсуждении редких и нереальных, но потенциально возможных проблем. Если за разумное время не удаётся придумать, как обойти минорную и редко воспроизводимую проблему – мы просто договариваемся, как с ней жить.
  • Не озвучивать вовремя возникшие проблемы, пытаясь решить всё самостоятельно (обычно ночами). Такой героизм ведёт лишь к провалам сроков, усталости и чувству недооценённости: «я тут подвиги совершаю, а меня ещё и критикуют за медленную работу!»
  • Болезненно реагировать на критику кода и уходить в выяснение отношений. Даже если коллега говорит, что код копролит так себе («а давайте всё перепишем!»), отнеситесь к этому с пониманием и обсудите, почему он так считает. Для вас лично это не менее полезно, чем для сервиса в целом.
  • Переходить на личности. Критикуя код или решение, мы критикуем только код или решение, но ни в коем случае не того, кто его написал или предложил. С учётом предыдущего пункта не стоит бояться критиковать. Лучше разумное время поспорить с коллегами, чем отправить в прод неудачное решение.

Итого

Здесь можно написать ещё о миллионе вещей. Но чем короче пост, тем проще его дочитать, а я очень на это надеюсь. И да, мы все еще в процессе становления и очень мобильны и подвижны и двигаемся вперед в ногу с развитием технологий и развитием подходов к управлению проектами, поэтому правила наши меняются. Напоследок приведу цитату Вольтера: Глуп тот человек, который остаётся всегда неизменным.