Что влияет на качество продукта и на время, которое на него затрачено
Меня зовут Денис Деркач, и я сотрудничаю с Dev.Pro в роли Senior Software Engineer. В этой статье я хочу рассказать вам о том, какие практики используют разработчики в мировом комьюнити и что нужно учитывать, чтобы разработать хорошее приложение в адекватные сроки.
Не всегда время, которое мы тратим на разработку, оправдано. Но и не всегда урезание бюджетов и отказ следовать практикам, которые признаны мировым сообществом, приведет к эффективному результату и не доставит больших проблем в будущем. В этой статье мы обсудим, что влияет на качество продукта и время, которое на него затрачено. А также определим, как найти баланс, чтобы удовлетворить душу разработчика, который всегда стремится все улучшить, и клиента со своим видением, которое может отличаться от вашего.
Когда можно считать, что с нашим приложением все в порядке?
Есть несколько критериев, по которым стоит измерять то, насколько качественным можно считать код.
- Код исполняет задуманное. Даже если можно поспорить с тем, что функция важнее формы, вряд ли получится опровергнуть то, что функция является основополагающей. Если код не исполняет задуманное, то это проблема.
- Следует одному стилю описания. Лучше, когда код написан в одном стиле — так будет легче и вам, и коллегам, которые будут взаимодействовать с ним после вас.
- Его легко понять. Это важный пункт, поскольку с этим кодом в дальнейшем будут взаимодействовать специалисты разного уровня, и стоит учитывать, что не все смогут разобрать тяжело написанный код.
- Наличие документации. Код может меняться, и единственное, что позволяет нам понять, как правильно поступать в разных ситуациях — это документация, которая сохраняет много времени и нервов. Поэтому вести ее следует регулярно.
- Код может быть протестирован. И желательно, чтобы сделать это можно было без рефакторинга, ведь рефакторинг — это дополнительный риск.
Практики, признанные мировым комьюнити
Принцип YAGNI. С английского аббревиатура расшифровывается как «You aren’t gonna need it». Идея принципа заключается в том, что не стоит реализовывать возможности, которые не были описаны в требованиях к системе. Придерживаясь этого принципа, заказчику не придется оплачивать лишние функции, а разработчики не потратят свое время на реализацию ненужного компонента.
Fail fast. Этот принцип утверждает, что проверять инпут стоит как можно раньше. К примеру, у нас может быть UI и бэкенд, и оттуда нам могут отправлять определенные данные, которые должны сохраниться в базе данных. В теории мы можем оставить валидацию на уровне базы данных, и БД подтвердит, что эти данные не валидны и их не стоит обрабатывать. Но если подумать о том, какую длинную цепочку прошел невалидный инпут от юзера, браузера и до базы данных, то сделаем вывод, что обработка инпута на UI заняла бы значительно меньше ресурса.
Защита кода. Всегда нужно писать код секьюрно, не забывая о разных видах атак, ведь даже в небольших продуктах можно столкнуться с проблемами такого рода. Существует два надежных способа избегать атаки: использовать только проверенные пакеты и выполнять проверку своего кода на наличие уязвимости. И то, и другое может предотвратить большие проблемы в будущем.
Используйте рефакторинг по предназначению. Сперва нужно оценить риски и понять, к чему рефакторинг может привести. Код, который вы видите, не обязательно плохой изначально, он может быть просто написан по-другому. Рефакторинг же стоит делать, когда есть риски в коде.
Работайте с tech debt. Когда мы видим часть, которую стоит улучшить, то очень важно опираться на существующие процессы в команде и говорить о них. Оптимально, если в команде выделяется время для работы с техническим долгом. Порой заказчик не видит необходимости переходить на новый тест-фреймворк, аргументируя это тем, что существующий также рабочий. Но по итогу техдолг может привести к проблемам в приложении.
Нефункциональные требования и способ их описать
Нефункциональные требования — это точные критерии, определяющие, как система должна работать. Они включают в себя системные атрибуты, которые устанавливают, что система может и не может сделать.
Главные типы нефункциональных требований включают в себя:
- вместимость;
- масштабируемость;
- эффективность;
- доступность.
Представим, что мы разрабатываем бэкенд и понимаем, что выдержим 1000 реквестов в секунду. И хорошо это понимать и учитывать, но задача усложняется, если мы никогда об этом не думали. В таком случае 100 реквестов, свалившихся на голову, могут принести много нежелательных проблем.
Как же тогда описать нефункциональное требование, если у вас его на проекте нет?
Разберем ситуацию: мы получаем негативный фидбэк от клиента из-за того, что UI долго загружается. Чтобы сделать из этой задачи нефункциональное требование, нам нужно иметь для себя порог того, что значит быстро/долго. Поэтому, в случае получения подобных фидбэков, я бы рекомендовал определить, что значит быстро/плохо и так далее, ведь это понятие для каждого может быть разным. После все результаты стоит задокументировать.
Как разработчики мы не знаем точно, что случится с нашим бэкендом, если он получит 10 000 реквестов в минуту. А это значит, что лучше еще до начала использования приложения сделать performance test и утилизировать имеющиеся тулы для того, чтобы определить нефункциональное требование. Если в той точке мира, где клиент использует приложение, завтра будет праздник, то мы можем предположить, что стоит ожидать много реквестов. И у нас есть два варианта: либо показать клиенту цельную картину, указав, сколько реквестов система точно выдержит, или заранее предложить помощь и готовность подключиться в любой момент и решить проблему, если такая нужда возникнет.
Что еще влияет на качество и время, затраченное на разработку?
Команда и окружение, в которой мы работаем, играет важную роль в том, насколько хорошим получится приложение и насколько точно мы будем понимать, что от нас требуется и как это осуществить.
Работа в команде, где мы можем поделиться своим мнением, может улучшить конечный результат продукта. Часто бывает, что мы не можем сказать о своих болях и не знаем точно, к кому можем подойти и поговорить. Сложности, с которыми разработчики сталкиваются, могут быть с разными и касаться не только кодинга, но и профессионального и личного развития, что тоже влияет на производительность специалиста и, как следствие, всей команды.
Возможность получать регулярный фидбэк дает понимание того, что вас ценят и работа, которую вы делаете — важна. Стоит учесть, что негативный отзыв — это тоже нормально. Не стоит переживать и расстраиваться, гораздо эффективнее будет использовать эту ситуацию как зону роста, проанализировать ее и знать, как избежать ее в будущем.
Еще один важный пункт в разработке — release cycle. Он дает более точное понимание того, когда наша работа должна быть закончена. Если этого нет, то создается впечатление, что неважно, когда будет релиз, и мотивация падает. Помните: Less fire is always better than more fire, поэтому планирование и подготовка имеют значение.
Разработчики — разрабатывают
Один из пунктов, который также влияет на время и качество разработки, это возможность разработчика заниматься программированием в том, в чем у него есть наивысшая экспертиза.
Популярное направление в мире JavaScript на сегодняшний день — Full Stack. В реальности довольно очевидно, что каждый из нас, пускай даже Full Stack разработчик, имеет большую экспертизу в одном из направлений. В разработке случается, когда фулстекам нужно заняться чем-то, в чем у них низкая экспертиза. В таком случае это будет занимать много времени и качество производительности может упасть. В идеале разработчики занимаются только девелопментом того, в чем у них самая сильная экспертиза, и развиваются в том, где экспертиза чуть ниже.
Если чего-то нет, то значит ли это, что наше приложение плохое?
В предыдущих главах мы обсудили best practices и условия, при которых работа будет выполняться наиболее эффективно и быстро. Но должны ли мы считать, что наше приложение плохое, если нет какого-то из перечисленных ранее пунктов?
Предложу начать обсуждение этой темы с уточнения терминов «кодер» и «програмист». Кодер — это человек, который может написать код. Программист — это специалист, который думает о задаче более абстрактно, рассчитывает все риски и только после этого переходит к исполнению задачи.
Поэтому вопрос, который всегда стоит задавать себе: «Пробовал ли я что-то изменить в приложении?». Если, к примеру, вы видите, что используется старый тест-фреймворк, который не поддерживается, то первое, что следует сделать — поговорить с кем-то из команды. Это уже шаг в сторону того, чтобы ваше приложение стало лучше. Скорее всего, после этого проблема решится. Главное — говорить, если вас что-то беспокоит в коде.
Если же вы сделали все, что могли, но вас не слышат, есть несколько решений:
- Продолжить работу.
- Взять отпуск.
- Найти ответ на вопрос, почему так происходит.
Представим: мы хотим улучшить наш CI/CD процесс и добавить pull-request jobs, и оцениваем эту задачу примерно в одну неделю. Стоит помнить, что нужно подготовить весомые аргументы, прежде чем идти с предложением к менеджеру или клиенту. Примеры плохих аргументов:
- Так делается везде.
- У меня было так на предыдущем проекте.
- Мне это нравится/не нравится.
Вместо этого вы можете сказать: «Мы потратили Х часов и Y часов на исправление ошибок. В сумме мы потратили Х + Y часов на решение определенной проблемы, и я уверен, что если мы выполним эту задачу, то в будущем у нас таких проблем не будет».
Также стоит сделать два списка аргументов для того, кто не понимает код, и для того, кто это понимает. К примеру, техническому человеку будут интересны технические детали реализации, в то время как нетехническому специалисту лучше объяснять проблему в рамках времени и бюджета.
Далее важно понимать, в каком состоянии сейчас находится проект.
- Если команда сейчас часто сталкивается с проблемами в продакшене, то, скорее всего, улучшение CI/CD не стоит в приоритете.
- Стоит уточнить, может ли заказчик выделить вам время и входит ли это в бюджет.
- Понять, есть ли человек, который может это осуществить технически, и кто именно сможет это сделать.
- Выбрать момент. Просите рассмотреть вашу идею в те дни и встречи, когда это уместно.
Как найти баланс и писать код, который удовлетворит и разработчика, и заказчика?
- Всегда держите фокус на том, в каком состоянии находится ваш проект. Если он длинный и должен выехать в продакшн через год, то есть время, чтобы использовать все best practices. Если же это proof of concept, то тратить много времени — это не совсем то, что нужно продукту, и приемлемо, даже если там будет несколько багов, поскольку этот продукт только тестируется и его работоспособность только определяется.
- Старайтесь готовить эстимейты. Реализация чего-то более сложного — это дороже, так как занимает больше времени. Тем не менее это может сэкономить еще больше времени и денег в будущем, поэтому риски стоит учитывать заранее.
- Определитесь, какие именно best practices из тех, которые вы хотите применить к продукту, действительно важны и без них никуда, а от чего можно отказаться. Один из трюков — стараться делать два эстимейта на какую-то большую задачу. Тогда это даст вам видение того, что можно улучшить и как этого достичь оптимально.
- Просите фидбэк и общайтесь с участниками команды. У вас может быть большой опыт, но все равно есть моменты, которые вы один не всегда можете учесть.
Как видите, в основе должно лежать понимание того, с каким продуктом мы работаем, на какой стадии и с какой целью этот продукт разрабатывается. После дело за малым — знать best practices, понимать их уместность, не бояться говорить, уметь подобрать правильный момент и веские аргументы, которые докажут, что ваши улучшения помогут проекту.
12 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів