Об оценках трудозатрат

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

Прежде всего, «точных» оценок не существует в принципе. Трудозатраты — это всегда случайная величина, подчиняющаяся некоторому распределению вероятностей. Внешне оно выглядит примерно так :

В этом примере вероятность завершения задачи за 4 дня равна 0.5, за 6 дней — 0.75, за 8 дней — 0.9.

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

Когда от нас требуют оценку трудозатрат, мы обычно устанавливаем для себя какой-то примерный порог вероятности. Например, если мы поставим порог 0.9, то наши оценки будут выполняться в среднем девять раз из десяти.

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

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

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

Но давайте задумаемся: а действительно ли мы решаем одни и те же задачи?

Вот представьте. Мы ставим задачу программисту – скажем, написать функцию вычисления квадратного корня. Программист потратил на неё, например, три дня, ещё день ушёл на тестирование и исправление ошибок.

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

Мы хвалим его и даём ему третью задачу: написать функцию извлечения квадратного корня.

Через пару месяцев производительность программиста стабилизируется, и он сможет выдавать по три функции вычисления квадратного корня в день. Исходя из этой производительности, мы сможем выдавать очень точные оценки… Оценки трудозатрат на написание функции вычисления квадратного корня.

Абсурдность примера очевидна, но он демонстрирует базовую проблему, заложенную в большинство способов оценки трудозатрат. Программисты никогда не решают одни и те же задачи. Все задачи уникальны.

Конечно, очень часто в программировании используются типовые подходы к решению определённых задач — разного рода шаблоны и фреймворки. В разных областях программирование может включать больше или меньше рутинных задач. Но правда состоит в том, что рутина обычно автоматизируется (или отдаётся неопытному молодняку, который вносит свою долю непредсказуемости), а основная доля неопределённости скрывается именно в той части задачи, которая составляет её уникальность.

При этом возмущение заказчика совершенно искренне: с его точки зрения мы действительно решаем одни и те же бизнес-задачи. Я почти десять лет проработал в очень узкой области — разработка приложений для терминалов, принимающих банковские карты. И с точки зрения бизнес-заказчиков, все эти десять лет я бесконечное количество раз решал абсолютно одну и ту же задачу: «научить» терминал выполнять продажу по карте клиента. С технической же точки зрения ни одна их этих задач не была похожа на другую. Количество параметров, по которым они отличались, огромно: разное железо, разные языки, разные компиляторы, разные протоколы, разные пользовательские интерфейсы… Но для бизнеса это всё несущественно — терминал либо выполняет транзакцию, либо нет.

Можно ли с этим что-то сделать? Как учитывать неопределённость при планировании проекта?

Наиболее распространённый способ: заложить при планировании как можно больше рисков и выдать оценку, в которую можно уложиться с максимально возможной вероятностью. Эта «максимальная возможность» определяется, во-первых, степенью наглости менеджера и его готовностью торговаться с заказчиком, а во-вторых — степенью запущенности его паранойи, проявляющейся при учёте рисков.

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

Намного лучше способ, позволяющий бороться с неопределённостью её же оружием — теорией вероятности. Существует множество вероятностных методов оценки, из которых наиболее известным (по числу упоминаний в учебниках) является метод PERT, а наиболее надёжным (по моему личному опыту) — практика Planning Poker. Хотя приверженцы Agile, скорее всего, не задумываются о вероятностных механизмах, заложенных в этот метод, а просто берут и делают.

Planning Poker даёт на удивление точные оценки. Фактически с его помощью мы учитываем в очередной оценке коллективный опыт решения всех предыдущих задач и основные риски. Но успешно применять его может только хорошо слаженная команда опытных разработчиков (читай: Agile-команда).

Радикальный способ решения проблемы предлагает теория ограничений. Метод критической цепи предполагает полный отказ от оценок с высокой вероятностью. Вместо этого предлагается давать оценки отдельных задач с вероятностью примерно 0.5, закладывая общий временной резерв на весь проект.

Но это способ действительно радикальный. Чтобы он сработал, требуется изменить общую проектную культуру организации.

Сделайте паузу. Прочитайте ещё раз, медленно, вдумываясь в смысл: требуется изменить общую проектную культуру организации.

Попробуйте прикинуть, сколько людей в вашей компании строят свою работу вокруг модели «точных оценок». Отдел QA планирует тестирование, исходя из предполагаемых сроков завершения итераций разработки. Отдел продаж включает эти оценки в договор с клиентом, но в договоре это называется уже не «оценками», а «сроками поставки». Отдел маркетинга анонсирует дату выпуска очередной версии «убийцы конкурентов» в своём пресс-релизе. И подо всем этим подписывается Самый Главный Босс.

А теперь представьте, что вы говорите всем этим людям: «С завтрашнего дня мы даём все оценки с вероятностью 0.5».

Нет, так они не поймут. Вы говорите вот так: «С завтрашнего дня мы будем выполнять только половину своих обещаний по срокам».

То, что вы услышите в ответ, и будет квинтэссенцией проектной культуры вашей организации.

 

Добавить комментарий