Тыкая пальцем в небо, или эволюция одной метрики
Это заметка выросла из ненаписанного комментария к колонке Сергея Малярова «Простой путь» — поделюсь, какими способами мы пользуемся, чтобы снизить неопределенность оценок в разработке и запрошу идей по усовершенствованию.
«Миссионер средневековья рассказывает, что нашёл точку, где небо касается Земли»
Гравюра Камиля Фламмариона, раскрашенная Хуго Хайкенвельдером;
По сути, объект, которым торгует программист — это человеческое внимание. Оценка трудоемкости и собственно программирование сходны меж собой в том смысле, что оба процесса представляют собой декомпозицию задачи на более мелкие части и привлечение внимания к каждой из этих частей; в случае программирования — подробное, с точностью до запятой, а в случае оценки — приблизительное, с точностью до подсчета элементарных пунктов в соответствии с выбранной детализацией. Что из этого следует:
- в целом, оценивать можно те задачи, декомпозиция которых очевидна. Если у нас в проекте есть нетривиальные части, то мы их можем оценить только приблизительно, с границами диапазона точности, отличающимися на порядок. Поэтому имеет смысл при оценке отделять типовые задачи от исследовательских и оценивать их отдельно.
- идеальная оценка подзадачи — это фактически ее реализация, трудоемкость оценки пропорционально трудоемкости задачи.
- неточности в списке подзадач накапливаются, неточность всей оценки является суммой неточностей подпунктов.
Когда я начинал оценивать задачи, то, исходя из этих наивных представлений, построил следующую простую форму сбора метрики, которая имела следующий вид — задача разбивалась на подзадачи, для каждой из которых в табоице записывались следующий колонки
Подзадача * Первоначальная оценка (ч) * Уточненная оценка (ч) * Фактическая трудоемкость (ч) * Осталось (ч)
Капитан очевидность одобрительно кивает головой: мы делаем оценку нескольких простых задач, уточняем таким образом статистику получаем ее .. и .. и ... все равно регулярно промахиваемся. То есть сбор этой метрики может и улучшил у нас качество планирования, но все равно не избавил от излишней оптимистичности.
Помедитируем и представим себе сферического программиста в вакууме, который в потоке поочередно направляет свое внимание на небольшие пункты приблизительно одного размера и решает их. Если оценка этих небольших пунктов распределена равномерно и независимо, то количество таких пунктов за единицу времени будет характеризироваться распределением Пуассона.
Вот рядом 2 графика распределения плотности вероятностей — Гаусса, с 20%-ной дисперсией, которое привычно нашему интуитивному представлению о вероятности, и Пуассона. Что мы видим:
- распределение Пуассона ассиметрично и смещено влево (то есть, если мы ошибаемся, то мы скорее всего недооценили задачу, а не переоценили)
пик значительно ниже: ожидание равно дисперсии. То есть, если мы оценили задачу наилучшим образом, то вероятность попадания все равно будет около 1/2. Обычно, если у разработчиков спрашивают, когда задача будет готова, то, вероятно, хотят услышать не наиболее вероятную оценку длительности работ, а время, в течение которого все работы закончатся с фиксированной верятностью.
Итого — во второй версии таблички сбора метрики у нас каждая строчка имеет вид:
Подзадача * Первоначальная оценка (ч) - min * Первоначальная оценка - max * Уточненная оценка (ч) * Фактическая трудоемкость (ч) * Осталось (ч)
Также мы знаем, что сумма уточненных оценок — это оценка случайной величины, распределенной приблизительно в соответствии с распределением Пуассона.
Вдумчивый читатель наверняка уже вычислил, откуда берется lambda (интенсивность потока событий): если одно событие — это какая-то элементарная единица трудоемкости, то относительная интенсивность — это количество таких единиц в одном акте декомпозиции (то есть, фактически, на сколько подзадач в среднем разбивается одна наша большая задача). Естественно, оценка может быть иерархической.
Все ? Как бы не так. На самом деле, эта модель тоже довольно наивна: наш сферический программист в ваккуме движется только вперед, он не исправляет ошибок и не задумывается о том, что в свете последних изменений требований, первоначальная архитектура нуждается в корректировке. То есть, на каждый объем сделанной работы приходится еще какой-то объем возникающего технического долга. И чем выше связность программы, тем больше этот объем технического долга зависит от общего объема уже написанного кода.
Итого, следующая инкарнация нашей таблички имеет вид:
Подзадача * Первоначальная оценка (ч) - min * Первоначальная оценка - max * Уточненная оценка (ч) * Фактическая трудоемкость (ч) * Осталось (ч) * Технический долг * Ошибки
В двух последних столбцах мы пишем оценку технического долга, возникающего после завершения итерации, и суммарную трудоемкость исправления ошибок за время жизни программы.
Почему технический долг пишется отдельно — потому что нам интересно отношение величины технического долга к размеру задачи. Если оно со временем превышает какую-то определенную величину, значит, надо что-то делать со связностью (или смириться с тем, что система стала более инерционной).
Собственно, почти в таком виде метрика ведется и сейчас. (Точнее — у нас еще есть три добавочные колонки, отражающие состояние процесса, исполнителя и примечания). Пока репрезентативных статистических данных о том, как именно они помогают — нет, субьективно — стало лучше. Анализ существующих данных также обнаружил некоторые вещи, противоречащие интуиции (стоимость ошибок оказалось меньше, чем ожидалось, а стоимость задач анализа — больше). Я еще думал о том, чтобы отслеживать распределение задач по типам работы, но это упирается в отсуствие удобного интерфейса тракинга, а утяжелять процесс или писать поддерживающее специализированное ПО не хочется.
Можно ли как-то выделить способы разработки, дружественные планированию? Да, если стараться, чтобы:
- объем планирования был как можно меньше (инкрементальные релизы)
- взаимосвязи между пунктами оценки были как можно меньше (исследовательские задачи делать в отдельной итерации и не смешивать с обычными)
- объем программы был как-можно меньше (высокоуровневые языки, библиотеки)
- связность модулей была как можно ниже (фреймворки и изменения базовой арзхитектуры делать в отдельной итерации и не смешивать с функциональными)
Как подобный подход соотносится к agilе, можно ли всю эту пляску с вероятностями заменить простой метрикой — соотношение идеального и реального времени?. Ну, в принципе, да, как любую дифференциируемую функцию можно заменить линейной в окрестности определенной точки. Методика ХP даст нам множитель, переводящий идеальное время в реальное, работающий в окрестностях какой-то точки и для какого-то проекта. Мне там не нравятся две вещи:
- Этот множитель получается большим и неинтуитивным, который предлагается просто принять как данное и смириться.
- Предлагается оценивать время в часах на реализацию, включая все остальные активности (документация, митинги, и т.д.) в этот большой коэффициент переноса. Получается, мы измеряем вещи уровнем ниже, чем сам процесс разработки. С другой стороны стоит отметить, что прогноз именно в продуктивных часах играет и позитивную роль, это по сути аналог «к-ства точек функциональности, длиной в один чаc», и именно фокусировка в часах делает эту оценку более или менее однозначной, просто она имеет другой физический смысл, чем время работы.
А в нашем варианте статистические коэффициенты соотвествуют физическому смыслу модели и берутся более или менее осмысленно — ими можно управлять, степень корректности декомпозиции задач можно формально проверить, и порождающая метрика дает нам представление о ходе проекта.
В заключение следует напомнить, что сама оценка времени в общем виде по-прежнему невозможна — описанные приемы не развеивают туман, а просто дают нам некоторые навыки ориентации в этом тумане, вместо источника света — знание о том, что в тумане ближние предметы кажутся приблизительно в два раза дальше, чем они есть на самом деле.
С моей точки зрения, ценность оценки трудоемкости состоит не в том, что мы можем получить какую-то цифру и сказать ее клиенту: за пределами одной-двух итераций это все равно слишком неточно, а в том, что разработка, сопряженная с процессом непрерывного планирования, идет проще и, в случае заказной разработки, лучше представима для клиента. Правда, при этом клиент должен понимать статус и ограничения этих оценок.
Все про українське ІТ в телеграмі — підписуйтеся на канал DOU
12 коментарів
Підписатись на коментаріВідписатись від коментарів Коментарі можуть залишати тільки користувачі з підтвердженими акаунтами.