Планирование — важная задача не только для тимлида или менеджера. Часто разработчику приходится отвечать на вопрос «когда это будет готово?».

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

Есть несколько разновидностей вопроса «когда это будет готово?».  Простые, например: «Когда нам нужно начать, чтобы успеть к концу ноября?». Или посложнее: «Можем ли мы подключить ещё разработчиков, чтобы успеть раньше?». Этот вариант мы тоже разберем. 

Проблемы у разработчика начинаются уже с интерпретации вопроса. «Готово» — это готово к использованию, а не «почти готово». То есть, сделана реализация, есть тесты, проведена отладка, пройдено ревью, собран фидбек. Значит, для ответа на наш вопрос надо заложить все эти стадии тоже. Обычно разработчик отвечает что-то типа: «Будет готово, когда будет готово», — и  аргументирует это тем, что много «неопределенности». ОК, а как тогда анонсировать фичи клиентам, заключать контракты, синхронизировать работу между командами и в целом вести бизнес, если по каждой фиче много «неопределенности»?

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

При этом, в повседневной жизни люди прекрасно справляются с планированием. Например, не опаздывают на самолет. Но ведь там тоже много «неопределенности»: пробки на дороге, очереди в аэропорту. Давайте попробуем разобрать этот пример.

Итак, у нас есть «что» должно быть сделано — посадка на самолет, и «когда» — определенное время вылета. Вы не можете быть «почти» в самолете, когда он вылетает. Вы либо там, либо нет. Также вы не можете пройти мимо паспортного контроля. То есть, существуют некие стадии, которые нельзя проигнорировать. Точно так же, как тестирование и отладку нельзя выкинуть из скоупа работ по разработке.

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

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

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

Выходит такая схема: берем известное событие, например, дату релиза, и откладываем назад все стадии, которые надо выполнить, добавляя буферы на риски. Получаем дату начала работ.

Для наглядности можно построить диаграмму Ганта. Зеленым обозначим буферы по задачам. t1 - время начала проекта, t2 - время завершения проекта.

базовый случай
базовый случай

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

Наш пример с самолетом — это простой случай с одним исполнителем. Стадии были последовательны. Исполнитель не уйдет в отпуск в середине пути и не переключится на другой проект. Да и степень неопределенности все же была достаточно низкая. Но все же можно сделать еще некоторые наблюдения:

  • Проект в целом может быть новым для вас, но при этом состоя��ь из частей, понятных для оценки. Например, часть «добраться до аэропорта» не сильно отличается от других случаев, когда надо доехать до какого-то места к определенному сроку. Поэтому, поделив проект на стадии, часть из них можно точно оценить на основе своего прошлого опыта.

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

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

  • Составив свой план, вы можете определить зависимости от других исполнителей. Например, такси можно заказа��ь заранее, к моменту выезда.

А теперь давайте усложним эту модель.

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

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

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

зависимости, необходимые для начала работ по проекту
зависимости, необходимые для начала работ по проекту

Если работаем в спринтах, то округляем, сдвигаем дату на начало следующего спринта. Прибавляем длительность работ и получаем предполагаемую дату окончания проекта.

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

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

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

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

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

задача 2 попадает в очередь к исполнителю
задача 2 попадает в очередь к исполнителю

В-пятых, неопределенность бывает действительно высокой, но ее можно попробовать снизить. Например:

  • Планировать разные варианты реализации. Если не сработает основная гипотеза, то будет запасная.

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

  • Сузить область неопределенности. Вычленить те части, которые более понятны, чтобы сфокусироваться на анализе непонятных.

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

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

Давайте подытожим. Вот основные шаги, которые стоит соблюдать при планировании проекта:

  • Определить критерии готовности.

  • Составить список стадий и майлстоунов. Можно это сделать, начиная с конца проекта.

  • Оценить каждую стадию. Добавить буфер для каждой стадии. Подбирать буфер с учетом рисков для стадии и для проекта в целом.

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

  • Выявить боттлнеки.

  • Заложить отпуска и переключения исполнителей на другие проекты.

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

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

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

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

Давайте хотя бы начнем думать о возможных рисках и тогда планирование будет более реалистичным. А при реалистичном планировании и результат будет ближе к ожиданиям.

Это простая короткая статья и было бы сложно включить в нее все концепции и подходы по планированию, которые существуют. Да и есть другие материалы, где это уже описано. Например, книги Элияху Голдратта.