Практика создания и внедрения единого стайлгайда для команды разработчиков
Каждый разработчик приходит в новую команду со своими привычками, видением и стереотипами о процессе разработки, инструментах, оформлении кода. Волей‑неволей, он немного холиварит с коллегами, отстаивая их. Это естественное явление, но иногда оно может вносить неразбериху и отнимать драгоценное время.
Под катом короткий рассказ про личный опыт создания и внедрения стайлгайда в малых командах в фазе бурного роста. Не претендую на идеальность подхода: просто расскажу, что может ждать на этом пути.
Привет. Меня зовут Костя Орлов — я марафонец, музыкант, а ещё бэкенд‑разработчик в финтех‑компании Точка.
Когда вся команда — герои удаленки, селфи из офиса начинают претендовать на эксклюзив
Чтобы подвести к сути вопроса, нарисую реалистичную картинку, знакомую каждому, кто работал в небольших командах в фазе роста.
Всё по классике: в чужой монастырь со своим уставом
Итак, у нас есть проект, над которым работают два‑три человека в течении пары лет. У них как‑то настроены процессы, код‑ревью проходит на «ура», на стиль написания внимание особо никто не обращает. Код мёрджится, продукт строится, и в целом всё получается более‑менее складно, даже когда в «монастыре» нет прописанного устава.
В какой‑то момент компания решает активно развивать продукт, для чего нанимает ещё нескольких разработчиков, причём в предельно короткие — за одну‑две недели.
Первым в команду приходит хороший парень Гарольд (назовем его так). У него 5–10 лет опыта работы, свои привычки, своё видение написание кода. Он прочитал несколько хороших книг типа «Clean Code» Мартина, кучу статей на Хабре по этой же теме и при первом код‑ревью начинает робко строчить старожилам свои комментарии. Например, такие:
— А давайте везде использовать только пробелы, а не табы.
— Переменные в сообществе принято писать вот так, а не по‑разному. Есть вот такие соглашения, которые вполне себе существуют и живут.
— В IDE у кого‑то стоят неправильные переносы, и при мёрдж‑реквесте непонятно, что ты правил, потому что в диффе подсвечивается весь документ.
— Где‑то не написаны тайпхинты.
— Здесь переменная указана без дефолтного значения.
И так далее.
Да, почти всё это про стиль и соглашения, которые нужно знать, а где‑то это даже вкусовщина —, но речь у нас идёт про резкое расширение команды. И вот к проекту разом присоединяются ещё 3–4 новых разработчика. И опять каждый из них со своим бэкграундом, опытом и привычками.
Парни неплохие, но иногда холиварят
Конечно, у них есть что‑то общее, стек ведь один, но есть и масса нюансов, которые выливаются в ненужные обсуждения во время код‑ревью. А так как все мы любим код‑ревью и комментарии в них, нужно что‑то с этим делать.
Что же делать?
Наверняка есть много разных способов, которыми можно разрешить и предупредить возникновение таких ситуаций. Мой рецепт — написание командного стайлгайда. Причём важно, чтобы в этом процессе участвовало максимальное количество разработчиков из команды.
Во-первых, это хорошая возможность лучше познакомиться. Особенно, когда команда работает на удалёнке и только недавно собралась — прямо как в нашей недавней ситуации.
Во-вторых, это удобный случай пошарить экспертизу, поделиться решениями, выслушать объяснения, подискутировать, получить новые векторы для развития и материалы для изучения.
Теперь давайте попробуем набросать примерный план действий. У нас в Точке есть отличный инструмент — регулярные командные встречи, которые мы проводим в некоем подобии CRM с интегрированными элементами холакратии. На них вся команда обсуждает рабочие вопросы и предложения. С этого инструмента и начнём всё раскладывать по полочкам.
1. На очередной встрече заводим проект и вписываем туда вводные. Начать можно с названия и ответственных. Это нужно для самоорганизации, надзора и официального подключения к процессу нужных сотрудников.
2. Формируем скелет документа и обсуждаем. Начинаем с создания первоначальной структуры. Проще всего это сделать в том же Google Docs. Там все желающие смогут прокомментировать спорные моменты или накидать своих материалов и пунктов к обсуждению. Это сэкономит время на следующем этапе.
Примерно так мы обсуждали черновик нашего стайлгайда
Важный момент — именно инициатор всей этой движухи должен собрать первые материалы. Тогда остальные участники активнее подключатся к процессу.
В сети можно найти много таких гайдов для разных стеков. В них уже есть готовые подборки ключевых моментов и общепринятые стандарты оформления кода.
После начального наполнения документ расшаривается на всех членов команды. В нём собираются правки, идёт обсуждение в комментариях, изучаются пожелания и дополнительные практики.
В этом процессе крайне важно не негативить и обсуждать любые комментарии, даже если вам лично что‑то не понравилось. Нужно помнить, что у всех разное чувство прекрасного, равно как и набор знании. Следующий этап должен будет расставить все точки над i.
После первой волны обсуждения и правок даём отстояться документу пару недель. За это время вы наверняка соберёте отличный фидбек, внесёте все правки, и документ примет законченный вид для финального обсуждения.
3. Обсуждаем финальный вариант на созвоне — голосом фиксируем то, что команда накидала в процессе заочного обсуждения.
Практика показывает, что такие встречи могут затянуться. Где‑то будет больно, где‑то неприятно, где‑то спорно. Возможно, одного созвона окажется мало — тут всё индивидуально. Главное — получить первую версию вашего документа, которую можно внедрять в повседневную практику.
В нашем случае весь процесс от идеи и до первого релиза занял около месяца.
Что должно быть в документе?
1. Основные правила. Например, какие стандарты написания кода (PSR12 или PER в PHP, PEP8 в Python), инструменты автоформатирования и статанализа будем использовать.
2. Общие рекомендации по настройке окружения. Здесь можно написать инструкцию со скриншотами и путями, а также приложить необходимые конфиг‑файлы. Ещё важно указать, какая кодировка должна использоваться: IDE у разработчиков могут быть разные, и нужно унифицировать даже такие моменты.
Плюсом к предыдущему пункту выставляем перенос строки, глубину отступов и прочие моменты.
3. Наименование сущностей — следующий важный и большой блок. В нём нужно сразу приводить примеры, как надо и как не надо. Из общих вещей не забыть:
— как назвать модели, классы, переменные, миграции;
— как назвать таблицы в БД;
— в каком случае camel case, snake case или pascal case;
— правила: где используется единственное, где множественное число.
Пример с наименованием сущностей из нашего стайлгайда
4. Правила размещения кода — тоже важный блок. В нём можно описать, где и что размещать. В каких слоях: сервисы, репозитории, вьюхи.
Так мы начнём контролировать моменты, связанные с размещением кода.
5. Ещё бы добавил правила работы в Git: какие слои есть в проекте, как мы называем ветки, как разрешаем конфликты, какие правила ревью команда принимает для себя.
6. Использование паттернов, практик, инструментов — и вообще всё, что команда посчитает нужным.
Один из примеров общих рекомендаций
Что в итоге
Получаем гайд, к которому имеют доступ все члены команды. В него можно вносить правки и дополнения, на него можно ссылаться во время код‑ревью. Мы размещаем его в репозитории или Confluence и делаем максимально доступным и заметным. Любой из коллег теперь знает, где можно освежить память касательно действующих практик и договорённостей.
Так выглядит наш стайлгайд в Сonfluence
Да, внедрение гайда потребует времени. Придётся сломать некоторые привычки, унифицировать и стандартизировать разработку внутри команды, а может быть даже и внутри компании. Но оно того стоит.
Например, стайлгайд сэкономит вам кучу времени на объяснения, когда в команду придёт новый человек — достаточно будет переслать ссылку на документ. А ещё гайд избавит от ненужных споров!
Хорошо, гайд мы написали — теперь давайте представим, как мы можем расширить его действие, и что с ним делать дальше.
Автоматизация
«Всё что может быть автоматизировано, должно быть автоматизировано» ©. Возьмём, к примеру, мой стек — PHP. Разными программистами и компаниями создано много инструментов для автоматизации форматирования кода по заранее описанным правилам — это так называемые автоформаттеры или линтеры (в нашем случае, Pint).
Здесь мы задействовуем процесс CI/CD и встраиваем в пайплайн автоматическую проверку форматирования кода. Если форматтер находит какие‑то ошибки, пайплайн падает.
Что это нам даёт? На ревью мы перестаём тратить силы и время практически на все вещи, связанные с форматированием кода. Разработчику, который деплоит свой код, остаётся локально прогнать написанное и пушить уже чистоту. Конфиги под форматтеры делаются общедоступными внутри команды, и у всех всё будет одинаково.
После линтера задействуем статические анализаторы (мы используем Psalm). Это инструменты, которые отслеживают соответствие типов и помогают вылавливать баги. Такие инструменты также встраиваются в пайплайн и фейлят его, если находят ошибки, которые не заметил разработчик.
Момент с проверкой размещения кода также можно автоматизировать и внедрить в пайплайн.
Как работают подобные скрипты: вы пишете конфиг, в котором указываете, что и где можно размещать, а что нельзя. Например, в контроллерах можно использовать только сервисы, в джобах только сервисы и модели, в моделях вообще ничего, а во вьюхах не должно быть никакого бизнес‑кода. Так мы тоже избавляемся от ручной работы, ведь если разработчик позволил себе расслабиться, его код не пропустит даже пайплайн.
Автоматизация может быть небыстрым процессом. Факторов здесь множество: опыт членов команды, знания и готовность к внедрению определённых инструментов. Кроме того, влияет качество проекта и его открытость к нововведениям. Например, чтобы запустить автоформаттер в пайплайн, сначала нужно прогнать весь проект на всех слоях. Если проект большой, это может занять недели и даже месяцы.
Представьте: пять разработчиков пилят новые фичи, ветки постоянно сливаются. Пока прогнали ветку дева через автоформаттер, туда коммитятся разработчики и получают конфликты практически на пустом месте. В общем, это отдельная большая история, про которую можно делать отдельный рассказ.
В качестве заключения
В начале я упоминал, что подобные стайлгайды чаще всего нужны малым командам в период их внезапного масштабного расширения. Это может регулярно происходить в стартапах — там команды только начинают строить свои процессы. Такой стайлгайд, на мой взгляд, будет отличным стартом.
Будет ли гайд полезен в действующей команде? Наверняка. По тем же причинам, которые я проговаривал выше: упрощение и ускорение код‑ревью, стандартизация и автоматизация части разработки, использование общих инструментов. Польза обязательно будет, как и от любых других процессов, которые уменьшают в коллективе энтропию.
Ну, а если вам нужны примеры стайлгайдов, посмотрите на наш для PHP — закинул его на GitHub. И туда же добавил ещё три ссылки на похожие, которые видятся мне полезными для просмотра и изучения.