Рабочий продукт — прежде всего, или Когда не стоит увлекаться кодом и тестами
Когда приходится начинать или перенимать новый проект, всегда возникает заветное «а давайте все перепишем», «а почему технология X а не Y» и под конец — «а этот код писали индусы». Резюмируется все фразой «давайте перепишем и вместо Y используем X». Но когда начинаешь спрашивать: «Почему технология Y применима к этому проекту?». В ответ слышится невнятное: «Ну, новее, интереснее...», «Мне было бы интересно получить опыт по ней».
Дальше обычно спрашивают: «А как обстоят дела с тестами?». Ответ так же, как и на встречный вопрос «Какой вид тестирования интересует?», — невнятный... Обычно он повторяется, как мантра: «Юнит-тесты». А на просьбу «Продай-ка мне юнит-тесты применительно к этому проекту» в лучшем случае говорят: «Любую строчку кода стоит покрывать тестами, потому что так надо». О продаже юнит-тестов речь даже и не заходит. А теперь давайте попробуем разобраться, что не так с этими вопросами и ответами.
Чудо-оружие разработчика
История человечества представляет собой цепочку войн и конфликтов, которые обросли легендами и байками. Если присмотреться к ним, то станет ясно, что победителями становились не благодаря лучшей организации, силе духа или отсутствию проблем со снабжением, а благодаря чудо-оружию. Так появились в мифологии экскалибур, меч-кладенец, дюрандаль и др.
С развитием технического прогресса роль «вундервафли» сильно возросла. В XX и уже XXI веке многие военачальники объясняли свои проигрыши тем, что «у него-то сверхоружие, да вообще и гранаты у меня были не той системы». К чему эта аналогия? В разработке сейчас происходит тоже самое. Многие специалисты прикрывают свою криворукость или неграмотность использованием того или иного фреймворка, библиотеки или технологии, которая всю работу сделает за них. Как говорит народная мудрость, на сосенке не могут вырасти яблоки, но часто проблема не в инструментах.
В неокрепшем сознании девелопера рисуется идеальный фреймворк или библиотека с одной функцией «сделать_все_зашибись()», которая сделает все как надо без помощи мозгов разработчика. Рядом с методом «сделать все зашибись», как серебряная пуля, лежат юнит-тесты. По мнению 75% разработчиков, это та вещь, которая позволяет писать без багов. То есть нужно просто стоит внедрить в проект тесты. Причем часто люди просто не имеют понятия о том, что вообще-то существуют разные виды тестирования, и то, что они хотят внедрить в проект, — скорее всего, далеко не юнит-тесты.
Давайте разбираться по порядку: как поступать в той или иной ситуации и почему возникают эти проблемы.
Фактор времени
Если вы делаете свой личный проект, то это ваше личное дело, на каком языке или фреймворке вы его разрабатываете и сколько времени это все у вас занимает. Никто кроме вас, ну и может, пары-тройки бедолаг, которых вы совратите к себе в кунаки, не почувствует вашей боли.
Однако 99,99% разработчиков педалят на дядю, и при этом ответственность повышается в разы. Все потому, что в дело идут чужие деньги, которые вы берете за то, чтобы у заказчика не было технических проблем. Также для вас важным становится фактор времени. Как говорит народная мудрость, дорога ложка к обеду. Время выхода той или иной фичи становится для вас и клиента архиважным фактором. Прощелкаешь неделю — утратишь целевую аудиторию, конкуренты запустят что то поинтереснее.
В таком случае важен не инструмент, с помощью которого вы разрабатываете решение, а конечный результат. Под результатом я понимаю рабочий продукт, сданный в срок. Технологии и поддерживаемость кода в будущем отходят на второй план. Кстати, когда вы педалите на себя, попытайтесь тоже сфокусироваться на результате, а не на инструментах. Это будет очень полезно для конечного продукта.
Выбор технологии на проекте
Это очень щекотливая тема. Если заказчик «спускает» вам решение, то не надо с пеной у рта доказывать, почему стоит использовать другое. Постарайтесь выяснить, на основании чего он его выбрал. Если это обусловлено требованиями бизнеса, то не остается ничего другого, как подчиниться. Но если вы видите, что заказчик не прав, ваша обязанность — предупредить его. Причем аргументы типа «этого нельзя сделать, потому что сделать нельзя» тут не работают. Бизнес диктует условия, и бизнес же платит за них. Поэтому готовьтесь обосновывать каждое свое слово, каждую сказанную фразу.
Если же заказчик объясняет свое решение тем, что «я погуглил, и мне выдало», то смело включайте режим пламенного борца за полюбившийся вам фреймворк или технологию. Но опять же не забывайте про аргументы. Сразу подготовьте список линков на технологию, список компаний, которые ее используют, обучалки для новичков и так далее. Дайте клиенту погрузиться в технологию. Забудьте аргумент «модно, стильно, молодежно» — это не работает для бизнеса. Лучший инструмент — это тот, который вы досконально знаете. И если вы приведете примеры и покажете успешные проекты, сделанные вами на известном вам фреймворке или технологии, это будет лучшей его рекламой.
Как бы ни был заманчив новый инструмент — осознайте, что его использование — это риск. Риск натолкнуться на грабли, о которых вы еще не знаете. К тому же большинство модных, стильных, молодежных технологий и фреймворков, которые только начинают свой житейский путь, очень сильно хайпятся. Ясное дело, что большинство статей, докладов на конференциях и вопросов на форумах (заданных первопроходцами по граблям) будут посвящены именно им. Поэтому и у вас, и у заказчика может создаться искаженное впечатление, что все человечество их использует, а вы до сих пор стоите в стороне от прогресса. Это может привести к тому, что вместо того, чтобы сосредоточиться на результате, вы будете исправлять проблемы, вылезающие при обкатке нового тула или технологии.
Если у вас уже есть рабочая версия или компания разрабатывает продукт с дальним горизонтом планирования, можно пойти на оправданный риск, заранее проинформировав о нем заказчика. Однако, если заказчик — стартап, который нанял команду из страны третьего мира, продав дедушкину лесопилку и заложив бабушкино фамильное серебро в ломбард, то лучше не рисковать, а использовать то, что даст 100% результат.
Про стартапы
Работать в стартапах, с одной стороны, интересно, а с другой — чрезвычайно сложно. Почему интересно? Стартапы — это новые и не очень идеи (украинские стартапы не в счет, тут на 90% не новые идеи). В стартапах люди идут на риски. Тут можно протолкнуть что-то новое, использовать новый подход. Можно настроить все под себя. Не устраивает стандартный git-flow — не проблема, модифицируй. Хочется ввести свои стили кодирования — да не вопрос.
Но есть и обратная сторона. Если уже посчастливилось работать со стартапом, привыкните к мысли, что это проект с нуля. Как вишенка на тортике — полное отсутствие требований как таковых. Привыкайте к тому, что концепция будет меняться каждый раз, когда заказчик будет находить новых инвесторов. Так что главное, над чем стоит работать в стартапах, — это гибкость вашего решения. Внушите команде, что то, что вы делаете сегодня, — завтра вы будете дружно выпиливать. В настоящих стартапах мало кто знает, что будет в конце. И будет ли конец вообще. Свыкнитесь с мыслью, что для вас важны успешные релизы к сроку, покрытие тестами, оптимизация алгоритмов и чистота кода.
Животрепещущий вопрос — чистый код
Чистый код очень важен для дальнейшего развития проекта. Без понимания этого написать что-то более или менее стоящее не представляется возможным. Однако есть и кое-что важнее, чем чистый код — это работающий продукт! Если код продукта написан идеально, но при этом были пролюблены все сроки, а заказчик пошел по миру, потому что вы в очередной раз решили порефакторить метод — то, как по мне, лучше рабочий код с костылями и подпорками.
Всегда стоит понимать, где золотая середина. Если у вас распланированы бюджеты на три года вперед, и есть план развития продукта еще на 10 лет — то тут надо стараться писать хрустальный код. Процессы код-ревью, строгая типизация, линтеры, тесты и здравый смысл вам в помощь. Но, если заказчик в понедельник вечером говорит, что в среду утром код должен быть уже доставлен в Париж на сельскохозяйственную выставку, то понятное дело, что тут уже не до красоты, и надо писать лишь бы работало, как автомат Калашникова, потому что так требует бизнес.
Конечно, надо привыкать писать сразу хорошо, однако не всегда это выходит чисто физически. Понятное дело, всегда надо сказать заказчику, а лучше отписать письмом, что будет сделано как попало и переиспользование кода, написанного при столь сжатых временных сроках, будет весьма затруднительно.
И теперь задумаемся о проблеме так называемого индусского кода. Большинство наших разработчиков любят поливать парней с Индостана отходами жизнедеятельности, не вникая в причины, по которым был написан тот или иной кусок кода. Для начала примите за утверждение: наши говнокодят не меньше, а с количеством вайтишников в отрасли мы по говнокоду скоро будем впереди планеты всей. Так вот, попробуйте войти в условия разрабов, написавших тот или иной кусок кода. Против индусов работает закон больших чисел. На жалкие 40 тысяч кодеров и иже с ними в Украине приходится 1 миллион кодеров с Индостана. Понятное дело, даже если принять, что процент говнокодеров у них и у нас одинаков — то у них кодеров аналогичной квалификации будет на порядок больше.
Тесты
Вернемся к нашим баранам. Тесты несомненно важны. Они сразу помогают локализовывать ошибки без траты времени на их обнаружение при тестировании. Однако, чтобы тесты были, их кто-то должен написать. Плюс к этому вы должны позаботиться о настройке инфраструктуры CI системы. Тесты без CI мертвы. Их будут запускать единицы, да и то когда нечем будет заняться. Тесты — это такой же софт, как и ваш разрабатываемый продукт. Они рождаются живут, изменяются, устаревают и умирают. А теперь стоит понять, что это все время. К тому же тесты окупают себя через достаточно большой промежуток времени (адепты TDD — прошу не кидать в меня камни). А у нас уже понедельник, а поставка на вторник, потому что в среду сельскохозяйственная выставка.
Надо задаться вопросом, а стоит ли писать тесты. Может стоит написать, а в оставшееся время лучше пройтись по функциональности? Опять же девелоперского тестирования никто не отменял, и вот оно обязательно в любом случае! Да это просто проверка — работает или не работает фича, которую вы делали, после завершения работы над ней и до команды `git push`.
Не все тесты одинаково полезны. Можно написать тест так, что он будет обеспечивать нужный процент покрытия, но будет абсолютно бесполезен. Примеры таких замечательных тестов вовсю ходят по сети.
Выводы
Итак, что в сухом остатке? Увлекаясь так называемым «Technical Excellence», мы должны не забывать о главном — о продукте. Да, важен именно конечный продукт, а не тесты, кристальный код, использование новых технологий и методологий разработки. Никогда не стоит забывать, что конечный результат нашей работы — это не уходящий в ноль burndown chart, не 100% покрытие тестами кода, не выполнение условий линтера, а именно рабочий продукт — и есть цель, к которой мы должны стремиться.