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

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

Причин такой катастрофической разницы довольно много. Вот некоторые из них:

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

  • Ошибки топ-менеджмента в области процессов. Если на этом уровне все плохо, то все остальное вторично. Даже неверная система бонусов может привести к разладу в команде и полной блокировке разработки в конечном счете.

  • Человеческий фактор. Личные качества и человеческие пороки могут создать проблемы как остальным членам команды, так и всему проекту в целом. Главная проблема в том, что эту часть невозможно выправить никакими процессами. Только изменение поведения. Либо расставание.

  • Плохой процесс разработки. Эта тема касается всех инженеров без исключения. Сюда входит все, начиная от взаимодействия и работы с задачами, заканчивая тестированием и проведением ревью кода.

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

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

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

Код

Хорошо

  • VCS. Код находится под контролем версий (как правило гит).

  • Общий код. Любой член команды в любой момент времени может изменить любую часть системы.

  • Единый стиль кода. В команде все придерживаются стандартов кодирования, принятых для данного стека (языка, платформы).

Плохо

  • Отсутствие единого стиля. Каждый пишет код в том стиле, к которому он привык. Нет общих стандартов либо есть, но свой, совершенно отдельный от общепринятого.

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

  • Код имеет “владельца”. Программисты защищают свой участок кода от посягательства других участников.

Полезное

Среда разработки

Хорошо

  • Девелопмент среда. Разработка ведется в специальной development (dev) среде. Как правило, это локальная машина (возможно, с использованием Vagrant или Docker Compose). Эта среда у каждого разработчика полностью своя, и изменения в одной среде не могут влиять на другие среды разработки.

  • Разворачивание среды автоматизировано и происходит “одной кнопкой”. Это позволяет легко вводить в проект новичков, быстро и в автоматическом режиме распространять инфраструктурные изменения, работать без страха что-либо поломать, так как легко восстановить.

  • Инфраструктура как код. Распространение изменений конфигурации происходит через код проекта. Достаточно еще раз выполнить развертывание дев среды (с новым кодом проекта), как подхватятся все обновления.

  • Среда разработки максимально приближена к условиям продакшена. Если сервис работает на Linux, то и разработка ведется на Linux. То же самое касается и других аспектов.

Плохо

  • Разворачивание среды и настройка происходит по мануалам, либо методом “попробовал запустить — прочитал сообщение об ошибке — погуглил — исправил”. Дорого и неэффективно. Мануалы устаревают практически сразу после того, как их пишут. Новый человек может тратить дни на разворачивание среды с нуля.

  • Ручное обновление конфигурации. Всем разработчикам рассылается директива произвести локальные изменения настройки среды (например, доставить что-нибудь новое) для работы нового кода.

  • Общая база данных для всех разработчиков. Нагрузка от одного человека влияет на всех. Случайная поломка также тормозит всех остальных.

Качество

Хорошо

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

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

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

  • Команда ревьювит код друг друга (без фанатизма). Ревью — не только способ найти ошибки, но и способ учиться друг у друга.

  • Парное программирование. Техника эффективна не только между программистами. Она очень полезна в парах “программист и тестировщик”, “новичок и опытный”.

  • Continuous integration (CI). Репозитории проекта подключены к серверу непрерывной интеграции, на котором после каждого коммита проверяется стиль кодирования (через запуск линтеров), прогоняются тесты, осуществляется сборка проекта (например, компиляция).

  • В случае инцидентов проводятся пост мортемы.

  • Ретроспектива. Процесс непрерывно улучшается и на изменения влияет каждый член команды.

Плохо

  • Нет тестов. Работа нового кода проверяется только ручным способом, через прокликивание. Последствия катастрофические — скорость доставки низкая, а качество кода, скорее всего, неудовлетворительное.

  • Отсутствует код ревью. Разный стиль кодирования, изоляция программистов друг от друга, слабый обмен опытом, плохие решения в продакшене.

  • Программист считает, что фича закрыта, когда код попал в основную ветку. Новый код лежит мертвым грузом и не приносит пользы. Может устареть до попадания клиенту.

  • KPI. Активно используются количественные метрики: строки кода, выпущенные фичи, закрытые баги. Вместо ориентации на результат, разработчики стремятся выполнить KPI. Даже в случае, если это идет вразрез с задачами бизнеса.

  • Высокий уровень формализации процессов. Замедляется скорость, падает мотивация.

Ссылки

Процесс разработки

Хорошо

  • Разработчики руководствуются принципами 12factors. Приложения проще разворачивать, масштабировать и мониторить.

  • Запуск одного теста выполняется за доли секунды. Разработка через тесты подразумевает очень частый запуск тестов в процессе отладки. В такой ситуации крайне важна скорость старта конкретного теста — она должна быть настолько быстрой, чтобы разработчик оставался в контексте.

  • Тесты писать легко и приятно. Лакмусовая бумажка для определения того, насколько хорошо с тестами в проекте. Если приходится себя заставлять, то есть вероятность, что тесты написаны плохо (например, много моков) и их будет недостаточно.

  • Test-driven development (TDD). По возможности тесты пишутся до кода. Есть несколько причин, по которым это важно:

    Тесты заставляют думать не о реализации, а о том, как тестируемый код будет использоваться. Благодаря такому подходу, программисты видят изъяны в интерфейсах на самых ранних стадиях.

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

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

Плохо

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

  • Запуск одного теста занимает секунды. Такой тест тяжело запускать при разработке через тесты и общее время выполнения тестов становится слишком большим.

  • Код правится прямо на продакшене (то место где он работает). Без комментариев.

Ссылки

Выкатка новых версий (более актуально для веб-проектов)

Продакшен-среда — инфраструктура (например, сервера), в которой развернут проект. Она обеспечивает доступ к проекту конечным пользователям.

Деплой (выкатка) — процесс, в рамках которого происходит обновление проекта в продакшен среде.

Хорошо

  • Автоматизация. Развертывание автоматизировано и выполняется одной кнопкой.

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

  • Zero Downtime Deploy. Обновление версии происходит прозрачно для пользователей.

  • Развертывание, технически (то есть все хорошо автоматизировано), может выполнить любой член команды.

Плохо

  • Выкладка происходит в ручном режиме. Например, через прямое управление с сервера. Самый ненадежный и не масштабируемый подход, подвержен ошибкам и может занимать значительное время. При наличии нескольких серверов просто не работает.

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

  • Процесс развертывания длится десятки минут или часы. Скорее всего, это означает, что процесс сборки проекта интегрирован с самим деплоем. Эти задачи нужно выполнять независимо.

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

  • Во время разворачивания наблюдаются длительные даунтаймы. Пользователи вынуждены ожидать завершения деплоя. Такая ситуация мешает деплоить часто.

  • Развертывание выполняет один специальный человек. Знания хранятся в одной голове. Уход в отпуск или болезнь ломает весь процесс. Остальные программисты не понимают “как оно работает там”.

  • Деплой конфигурации. Обновление конфигурации, не относящейся непосредственно к логике кода, требует повторного деплоя. Например, изменение пароля к базе данных или адреса базы. Эти параметры являются чисто инфраструктурными и должны попадать в код так, как описано в 12factors.

Комментарии (8)


  1. KongEnGe
    16.09.2021 12:55
    +10

    Когда понимаешь, что в пет-проекте у тебя больше хороших практик, чем в корпоративном.


  1. freeg0r
    16.09.2021 14:32

    ...Разворачивание среды автоматизировано и происходит “одной кнопкой”

    это как это? вам как минимум надо получить доступ к репо (положить ssh key на remote),
    установить плагины (*lint и тп), настроить VPN..., лицензии на инструменты..

    Упомянули Trunk Based Development, ни слова про git-flow. Кроме того по гиту тоже хорошо иметь соглашения по именованию веток и коммитов с обязательными ссылками на US, таски и баги (issues)

    Test coverage - nice to have на проекте и централизованый Sonar.



    1. therb1
      17.09.2021 20:16
      +3

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


  1. vladimir123456
    16.09.2021 14:32
    +5

    наивно...


  1. F0iL
    17.09.2021 08:41

    Проверил текущий проект, где я работаю, насчитал ~80% (кроме тех, что совсем неприменимы). И да -- у нас embedded и мы пишем под железки.


  1. F0iL
    17.09.2021 08:43

    Кстати, наверное стоило бы добавить еще про документацию для компонентов и фич (дизайн архитектуры в Confluence, acceptance criterias в JIRA, ну или хотя бы Doxygen-комментарии), а также использование статических и/или динамических анализаторов и линтеров кода.


  1. apavlyut
    17.09.2021 08:48
    -1


  1. maksasila
    17.09.2021 12:23

    В голосовании не хватает 0%.