Что является главным секретом успеха эффективной разработки IT-продукта?

Создание нового продукта с нуля (MVP), проверка гипотез, быстрые изменения на основе обратной связи или последующая поддержка, если продукт доказал свою жизнеспособность - процессы довольно сложные и дорогостоящие. Если верить статистике, 90% стартапов из всех проваливаются, 70% закрываются в первые 5 лет. Причины могут быть разные. Самая частая - ошибка в исследовании потребностей рынка (42%). Другими словами, продукт, который мы делаем, в реальном мире не так уж нужен. Данная проблема находится вне плоскости разработки, вследствие чего, мы не будем ее разбирать в данной статье. Вторую по частоте причину можно сформулировать примерно так - слишком рано заканчивается финансирование. Продукт закрывается до того, как выйдет на рынок или нащупает устойчивую бизнес-модель (29%). В данном случае, эффективность разработки может играть уже решающую роль для выживания продукта и успеха всей компании. Скорость и предсказуемость сроков итераций разработки, качество выдаваемого продукта пользователям, time to market новых фичей или гипотез - все это становится ключевыми факторами успеха.
Те же самые принципы актуальны для зрелой компании, которая смогла занять свою нишу на рынке. Особенно если компания на волне успеха начинает бесконтрольно масштабироваться, раздувает штат и становится неповоротливой. В конечном итоге она может проиграть конкуренцию более молодым игрокам, которым удается быстрее развивать свой продукт под потребности рынка или сделать его дешевле, за счет более эффективной разработки.
Главное заблуждение разработчиков
В эффективности процесса разработки заинтересованы все, в том числе сами инженеры. Чем проще и боле безболезненно команде удается деливерить изменения в продукт, тем комфортней становятся рабочие будни и выше боевой дух всех членов команды.
К сожалению, очень часто я вижу одну и ту же ошибку, которую совершают люди, с техническим складом ума, излишне фокусируясь на одном аспекте, кажущемся им решающим. На практике же, он может не давать никакого эффекта кроме психологического, оставляя все вышеперечисленные проблемы нерешенными. Начнем с самого яркого примера.
Выбор стека технологий
Самое интуитивное решение для инженера - найти самый лучший, новый, современный/разрекламированный инструмент и поверить в то, что на нем невозможно писать плохой код. Что можно реализовать ту же задачу в разы быстрее чем раньше, что багов будет меньше и т.д. Перечислю только то, что я непосредственно наблюдал на своей практике.
Ruby on Rails - MVC фреймворк нового поколения, где обо всем подумали за разработчика. Функциональное программирование (Clojure как пример) - отдельный мир для избранных, где не нужно страдать. TDD - максимальное покрытие кода тестами, ошибки отлавливаем раньше. Test First помогает лучше проектировать модули. NoSQL - гибкость и масштабируемость. GraphQL - не нужно тратить время на новые ручки API, фронтенд сам заберет все, что ему нужно. Знакомо? Можно продолжить. React.js - спаситель фронтенда, на который нужно срочно перейти с любого другого фреймворка и забыть о проблемах на клиенте. Redux - теперь уже точно на фронтенде полное счастье. По другому быть просто не может.
Неужели это все неправда? И да и нет. Технологии могут быть прекрасными, но они сами по себе не решают изначальную проблему эффективности разработки продукта, т.к это всего-лишь инструменты. Представьте, что вы строите многоэтажное здание в суровом климате с непростым природным ландшафтом и капризной почвой. У вас есть современные краны, пневмонагнетатели, лазеры для установки уровней и весь необходимый инструментарий в руках рабочих. Достаточно ли этого, чтобы построить устойчивое здание, которое простоит десятки лет и не разрушится под воздействием переменчивой окружающей среды? Очевидно, что нет. Ключевым фактором будет точный расчет архитекторов и инженеров нагрузки на опоры, исследование почвы на предмет пригодности к возведению высотных зданий и учет перепада температуры в зимнее и летнее время.
В разработке программного продукта ситуация примерно такая же. Что приводит нас к следующему фактору эффективности.
Архитектура
Если коротко - с посредственной архитектурой, используя даже самые лучшие инструменты, разработка будет эффективной очень недолго. Сроки в какой-то момент перестанут быть предсказуемыми, станут появляться дополнительные итерация баг-фикса и стабилизации релизов. Технический долг будет расти и отнимать все больше времени. И наоборот - даже с не самым современным стеком, инвестировав в архитектуру, можно обеспечить стабильное деливери для бизнеса. Может быть не на максимально возможных скоростях, но, что более важно, в предсказуемые сроки.
Короткий пример из мира фронтенда: популярная связка React.js + Redux. В какой-то момент хайп достиг такого уровня, что все новые проекты использовали данный стек, в полной уверенности в своем успехе. Проблема в том, что React это всего лишь view-библиотека для отрисовки компонентов, а Redux не умеет ничего, кроме сохранения состояния в один громадный глобальный стор. Эти две библиотеки, в теории, давали возможность написать что угодно, но не предлагали никаких идей по организации структуры приложения, модульности, разделению логики по слоям (view, business логика, application логика, API), выделению доменов и bounded contexts. В результате каждый React-проект был велосипедом, рандомно структурированным, с огромнымным скоплением логики на View-уровне или в Redux-сторе.
Какой можно сделать из этого вывод? В первую очередь нужно позаботиться о том, чтобы в долгоживущем проекте на старте было достаточно экспертизы для создания надежной архитектуры, и только потом выбирать инструменты. Подчеркну - именно экспертизы. Какую должность занимает человек при этом не так важно.
Но достаточно ли этого, чтобы вывести разработку на максимальные обороты, или есть еще что-то важнее архитектуры и инструментов? Кажется, что есть.
Управление и процессы
Этот пункт менее актуален в микро-проектах на старте, когда вся команда помещается в один опенспейс или в один daily-синк в Zoom. Но это не значит, что им можно пренебрегать. У нас есть архитектура и мощный стек, который помогает инженерам закрывать задачи быстро и с хорошим качеством. Но как организован процесс разработки? Проводит ли команда оценку перед тем как начать разработку? Распараллелен ли процесс разработки или все блокируют всех? В какой момент задаются неудобные вопросы по требованиям: в момент когда уже разработка началась или перед тем как дать оценку? Как распределяются задачи внутри команды? Нет ли дисбаланса, когда одна часть команды перегружена, а другая скучает? Рассмотрим пример:
Нужно добавить в продукт новый раздел с отзывами или комментариями, например, на товар. Эта фича включает в себя: новый дизайн, новое API, новый экран или виджет на фронте.
Вариант №1 - берем и делаем
Ждем дизайн (2 дня)
Посмотрели - вроде все хорошо. Начинаем делать API (4 дня)
API готово. Начинаем делать фронтенд (еще 4 дня). В конце сами себя спрашиваем "А должны новые отзывы появляться автоматически после загрузки или только при следующем заходе на страницу? Кажется мы это в API не предусмотрели...". Потратили еще 1 день на обсуждения и дополнительный костыль в виде периодического передергивания ручки с фронта. Параллельно уже боимся, что на проде API может стать плохо от такого объема запросов, но переделывать уже времени нет.
Отдаем в тестирование, фиксим баги (еще 3 дня).
Все протестировано можно мержить в мастер. Создаем огромный Merge Request, начинается код-ревью остальными участниками команды. Замечаний очень много, исправлять их долго и страшно т.к фича уже протестирована. Внесение серьезных изменений потребует повторного тестирования. (еще +3 дня)
Итого - 17 дней, уже имеем техдолг, а мы еще не на проде.
Вариант №2 - оценка, контракты, параллельная разработка
Дизайн не зависит от занятости команды, поэтому он рисуется заранее по первому запросу от бизнеса "в стол". На момент, когда команда готова взять новую фичу, дизайн уже готов.
Смотрим дизайн, задаем вопросы (в том числе про автоматическое появление новых отзывов). Описываем контракты для нового API, шарим их с фронтенд командой. Тратим дополнительно на эту подготовку 1 день.
Стартуем разработку бэкенд/фронтенд параллельно по контрактам, договорившись какие ручки API нужно выдать в первую очередь для интеграции. Как только появляются первые рабочие end to end-сценарии, QA начинает их тестировать и репортить баги, которые закрываются параллельно с разработкой. Декомпозируем фичу на мелкие задачи и выкладываем их на код ревью атомарно, по мере готовности. Оперативно ревьюим и правим замечания мелкими порциями (5 дней на все).
На этом этапе у нас уже закончена разработка и исправлена большая часть багов. Исправляем то, что осталось. (2 день)
Весь код уже прошел ревью на предыдущих этапах. Можно мержить в мастер.
Итого: 8 дней, без техдолга, с предварительной оценкой и пониманием когда фича будет готова к релизу на прод, с точностью до пары дней.
Кто за это отвечает? Чаще всего - тимлид. Хотя, как и в прошлом пункте, должность тут вторична.
Казалось бы, что на этом можно закончить, т.к теперь разработка уже несется на всех парах как локомотив, верно? Почти верно. У нас уже есть четкий план, инструкции, роли и инструменты, но не хватает самого главного.
Кадры и найм
Ингридиент, который я субъективно считаю самым важным из всех. Он может на практике, как нивелировать отсутствие любого из вышеперечисленных пунктов, так и не позволить им заработать уже на начальном этапе. То, с чего нужно начинать разработку любого серьезного продукта. Найм и формирование профессиональной команды.
Данная тема настолько обширная, что заслуживает отдельной статьи. Сейчас же, я лишь сформулирую основные тезисы:
Профессионализм и ответственность - качество номер один.
Проактивность. Человек на любой позиции в команде чувствует неудовлетворенность если видит какую-то нерешенную проблему. Он не ждет задачи сверху, а проявляет инициативу сам.
Soft-skills так же ценны как hard-skills, иногда даже ценнее.
Умение работать на команду. Довольно сложно проверить на этапе интервью, но возможно.
Почему это так важно? Это не всегда очевидно, но самая дорогая часть разработки это не сам процесс написания кода, тестирования или баг-фикса. Дороже всего обходятся лишние итерации на стыке разных стадий разработки и разных ролей в команде. С какого раза бэкенд-инженер выдаст по-настоящему рабочее API фронтенд-команде? Сколько раз нужно будет тестировщику перепроверять и возвращать на доработку одну и ту же задачу, перед тем как она будет пригодна для продакшна? Можем ли мы закрыть все вопросы по требованиям за одну встречу перед стартом разработки или будем постоянно стопориться в процессе спринта и на ходу додумывать корнер-кейсы?
Профессионалы, обладающие всеми перечисленными качествами, будут интуитивно экономить вам время на каждом из этапов, и их об этом даже не придется просить. Им небезразличен результат. Такая команда может эффективно деливерить даже с неидеальной архитектурой, не самым мощным стеком и даже без выверенных процессов. Поэтому, я считаю, что кадры - это самый главный фактор успеха эффективной разработки, на основе которого строится все остальное.
Заключение
Мой топ по мере важности выглядит так:
Кадры и найм
Управление и процессы
Архитектура
Стек технологий
В этой иерархии бывают исключения. Иногда выбор стека может существенно повлиять на структуру команды и процессы разработки. Например, кроссплатформенный фреймворк для мобильного приложения, как альтернатива отдельным командам iOS + Android, позволяет существенно сократить time to market в мобильном продукте, одновременно снизив стоимость разработки и тестирования. Об этом, возможно, будет отдельный пост. Но даже в этом случае, расставить приоритеты в предложенном порядке, с моей точки зрения, не будет ошибкой.
Спасибо всем, кто дочитал до конца. Надеюсь, материал оказался вам чем-то полезен. Данный пост носит сугубо обзорный характер. В будущих статьях планирую раскрыть каждый пункт более подробно. Оставайтесь на связи.


