Как правильно ставить задачи программистам

Николай Седенков, веб-разработчик 20.12.2019

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

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

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

Рассмотрим несколько абстрактных интернет-магазинов. В одном из них разрешено оформление заказа для неавторизованного посетителя, в другом — не разрешено, третий же в процессе оформления заказа производит автоматическое создание учетной записи пользователя, да еще и с «теневой» подпиской на рассылку рекламных предложений. В одном из магазинов информация о товарах и ценах автоматически обновляется в ходе периодического обмена данными с системой управления торговлей, в другом товары создаются и редактируются вручную, в третьем вообще импортируются из таблиц Excel с помощью специально созданного для этой цели скрипта. В магазине одежды или обуви покупатель должен выбрать размер и цвет приобретаемого товара (такие сочетания в ряде «движков» интернет-магазинов именуются торговыми предложениями), магазин бытовой техники, как правило, предлагает к своим товарам ряд расширенных программ гарантийного и постгарантийного обслуживания, магазин электроинструмента посоветует одновременно с перфоратором приобрести подходящие для него буры, зубила и пики. Один магазин предоставляет только почтовую доставку и самовывоз, тогда как другой способен определять местоположение покупателя и на основании этих данных рассчитать стоимость доставки курьерской службой. Где же среди всего перечисленного затерялся тот самый типовой, общий для всех набор функций, присущий всем этим магазинам, так сказать, «из коробки»?

Кроме того, следует учитывать, что любой веб-проект представляет собой довольно-таки слабо связанную систему. Любой раздел сайта, практически любую стороннюю библиотеку, как правило, можно изъять из проекта самым грубым образом, не наблюдая при этом каких-то фатальных последствий. Все сломается лишь в случае непосредственного обращения к отсутствующему разделу или библиотеке. Другими словами, в огромном количестве веб-проектов отсутствует хотя бы элементарное описание зависимостей, не говоря уже об автоматическом контроле наличия всех необходимых программных составляющих. Также отсутствует и какая-либо документация. Поэтому нередки ситуации, когда проект находится на поддержке уже не первый год, но при этом какая-то отдельно взятая функция за все это время ни разу не была затронута. Соответственно, несмотря на длительный срок поддержки, именно об этой функции, скорее всего, ничего неизвестно, поскольку с прочими частями проекта она никак не взаимодействует. И если владелец проекта внезапно решит, что для этой обособленной функции назрела необходимость доработки, для программиста, имеющего солидный опыт на проекте код этой функции окажется совершенно незнакомым.

Из всех приведенных рассуждений и вытекает взгляд исполнителя на постановку задачи. Задача, сформулированная очень лаконично («нужно сделать, чтобы вот там-то стало вот так-то») в абсолютном большинстве случаев вызовет огромное количество встречных вопросов. Также нередки случаи, когда задача поставлена, на первый взгляд, довольно развернуто, подробно описана проблематика, приведены примеры, но беда в одном: все перечисленное изложено исключительно с точки зрения человека, находящегося в контексте бизнес-процессов проекта, для которого проблема очевидна. Для программиста задача, поставленная исключительно с точки зрения бизнес-процессов, как правило, малопонятна.

Пример: поступила задача со следующей формулировкой «На примере набора <артикул набора> иллюстрирую проблему. Данный набор состоит из: <артикул товара 1> XXX руб, <артикул товара 2> — YYY руб, сумма по ценам отдельных комплектующих = XXX + YYY = ZZZ руб. А цена набора <артикул набора> XYZ руб. Как можно решить данную проблему? Т.е. мы предлагаем более привлекательные цены клиентам, если они берут наборы, а не товары по отдельности.» Проверка, проведенная исполнителем, показала, что сайт показывает цены верно: за товар 1 XXX руб, за товар 2 YYY руб, за набор XYZ руб, что меньше суммарной цены двух товаров. Появляется вопрос в чем состоит проблема? Вероятно, для заказчика она более чем очевидна и прямо вытекает из приведенных ценовых выкладок. Но для программиста очень полезной оказалась бы информация о том, что заказчик ожидает получить на выходе, после решения заявленной задачи. Другими словами, в тексте постановки задачи приведен пример с конкретными товарами, но никак не разъясняется ожидаемый конечный результат.

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

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

Какой же способ постановки задач с нашей точки зрения можно назвать качественным? Человек, формулирующий задачу, для себя уже уяснил, какова цель доработки, какие проблемы предстоит решить с ее помощью. Для исполнителя, чтобы достигнуть сравнимой степени понимания, весьма полезной будет информация о том, как именно функционирует условный предлагаемый к доработке инструмент на текущий момент, к каким результатам приводит его работа, а также что в этих результатах предполагается изменить. Далее, если работа функционала связана с какой-то визуальной частью, элементами интерфейса, с которыми пользователь взаимодействует в процессе работы, нелишне проиллюстрировать процесс работы с инструментом поэтапно, выделив на скриншотах ключевые операции. Это позволит составить представление об ожидаемом пользовательском сценарии взаимодействия с инструментом. Как вариант, можно сопроводить задачу непосредственно самим пользовательским сценарием, в котором по пунктам перечислить состав действий пользователя, причем если в ходе доработки сценарий изменится, разумно привести как исходный, так и целевой сценарии. В завершение следует детально изложить ожидаемый результат работы функционала, либо ожидаемый вид страницы после доработки. Такие сведения существенно помогут по завершении убедиться, что доработка проведена правильно.

Пример грамотной постановки задачи: «В настоящий момент на странице корзины работает следующая логика: в момент загрузки страницы проверяется общая сумма товаров и на основании этого устанавливается тот или иной обработчик нажатия кнопки “оформить заказ”; в случае изменения количества позиций (и как следствие изменения общей суммы заказа) функционал нажатия кнопки "оформить заказ" никак не меняется; требуется поставить работу кнопки "Оформить заказ" в зависимость от текущей итоговой суммы заказа без перезагрузки страницы». Как нетрудно видеть, подробно изложена текущая ситуация и, что особенно важно, разъяснена ожидаемая цель задачи. Такая формулировка вызовет минимум недоумения и встречных вопросов даже у человека, впервые увидевшего данный проект.

Приведенная методика постановки задач может показаться излишне трудоемкой, однако в конечном итоге она позволяет сэкономить время исполнителя, а значит и деньги заказчика.

Все статьи