Pull to refresh

Доказательное планирование

Reading time 13 min
Views 40K
Original author: Joel Spolsky
Примечание переводчика: оригинальная статья была написана в 2007-м году, однако, на мой взгляд, полностью сохраняет актуальность и сегодня.

Разработчики программного обеспечения не любят составлять план работ. Обычно пытаются вовсе от него отказаться. «Закончу, когда закончу!», — говорят они, ожидая, что этот смелый и веселый поступок вызовет одобрение у босса, а о планировании будет успешно забыто.

Большая часть расписаний, с которыми вы встретитесь, будет представлять из себя бездушные отписки. Совершенно забытые, они хранятся в каком-нибудь общем каталоге. После выпуска продукта с опозданием на пару лет странный парень, в чьем офисе, говорят, видели картотеку, принесет на обсуждение причин провала старую распечатку, которую все засмеют. «Только гляньте! Мы запланировали две недели, на переписывание системы с нуля на Ruby!»


Просто умора! Если вы до сих пор на плаву.

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

Почему разработчики формально не планируют свою деятельность? Тому есть две причины. Во-первых, это большой геморрой. Во-вторых, никто не верит, что планы будут соответствовать реальности. Зачем тратить время на составление расписаний, если они все равно разойдутся с действительностью.

За последний год мы в Fog Creek разработали систему, с которой согласились работать даже самые брюзгливые программисты. И, насколько я могу судить, она приводит к созданию очень точных расписаний. Система называется «Доказательное планирование» или ДП. Подход сводится к тому, что на основе анализа статистики выполненных работ собираются доказательства, которые потом используются для построения плана на будущее. В результате вы получаете не просто дату выпуска продукта, а и доверительную кривую распределения вероятностей завершения работ в каждый заданный срок. Выглядит она следующим образом



Чем круче кривая, тем более реалистична конкретная дата завершения проекта.
Вот как это делается.

1. Разделяйте…


Когда я вижу расписание, отдельные работы которого измеряются днями или даже неделями, я понимаю, что толку от него не будет. Нужно разбить планируемую деятельность на очень мелкие задачи, измеряемые часами. Максимум 16 часов.

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

Когда вы небрежно создаете трехнедельные задачи (например, «Реализовать редактор фотографий на Ajax»), вы понятия не имеете, что на самом деле хотите сделать. В подробностях. Шаг за шагом. А пока не обдуман точный план действий, вы не можете и знать, сколько времени это займет.

Устанавливая максимальную длительность задачи в 16 часов, вы заставляете себя обдумать эту чертову функциональность. А вот если отделаться трехнедельной работой под названием «Редактор фотографий на Ajax», то у меня плохие новости: с этого момента вы официально обречены. Не обдумав конкретные шаги выполнения задачи, вы неминуемо забудете о многих из них.

2. Считайте затраченное время


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

На самом деле, никак.

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



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

  • Мифический эксперт по оценке, который существует только в вашем воображении, будет всегда точно предсказывать время выполнения. Его история скоростей будет иметь вид {1, 1, 1, …}
  • Типичный плохой оценщик продемонстрирует очень большой разброс показателей, например {0.1, 0.5, 1.7, 0.2, 1.2, 0.9, 13.0}
  • Большинство экспертов, конечно, будет ошибаться, но в целом их оценка будет хорошей. Работа всегда требует больше времени, чем планировалось – очень трудно учесть исправление ошибок, планерки, перерывы на кофе и того сумасшедшего, который постоянно вас отвлекает. Этот типичный оценщик покажет достаточно стабильные значения скоростей, которые, однако, меньше единицы. Например, {0.6, 0.5, 0.6, 0.6, 0.5, 0.6, 0.7, 0.6}

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

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

3. Моделируйте будущее


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

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



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

Смотрите, что происходит

  • Для случая мифического идеального оценщика все скорости равны единице. Деление на скорость, которая всегда равна единице, ничего не меняет. Таким образом, все раунды моделирования дают одну и ту же дату завершения, и эта дата имеет стопроцентную вероятность. Прям как в сказке!
  • Оценки плохого эксперта очень сильно разбросаны. Это может быть и 0.1, и 13.0. Каждый этап моделирования приводит к сильно отличающемуся от остальных результату. Кривая распределения вероятностей будет чрезвычайно пологой, показывая одинаковые шансы закончить завтра или в далеком будущем. Кстати, это достаточно полезная информация — она говорит вам о том, что нельзя быть уверенным в назначенной дате выпуска продукта.
  • Усредненный типичный оценщик даст очень близкий друг к другу набор скоростей, например, {0.6, 0.5, 0.6, 0.6, 0.5, 0.6, 0.7, 0.6}. Производя деление на эти скорости, вы будете увеличивать время, отведенное на выполнение задач, например, 8-часовая задача на одном этапе моделирования может превратиться в 13-часовую, во время другого она займет уже 15 часов. Это компенсирует неискоренимый оптимизм экспертов по оценке. Причем компенсация будет выполнена точно, основываясь на свойственном именно этому разработчику, доказанному и проверенному временем оптимизме. И так как реальные скорости достаточно близки по значениям (около 0.6), запуская каждый раунд моделирования, вы получите сходные цифры, и в результате в вашем распоряжении будет достаточно узкий диапазон возможных дат завершения проекта.

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

Обсессивно-компульсивное расстройство не требуется

Что делать с бесконечными историями своего босса о его походах на рыбалку? Или с совещаниями, посвященными продажам, которые вас заставляют посещать без всякой видимой на то причины? Перерывами на кофе? Потраченной половиной дня на помощь новичку в настройке рабочего места?

Когда я и Бретт разрабатывали эту технику для Fog Creek, нас сильно беспокоили вещи, которые приводили к потерям времени, но в то же время не могли быть предсказанными заранее. Иногда на них уходило больше времени, чем на непосредственное кодирование. Должно ли это учитываться каким-либо образом и включаться в расписание задач?



Вы, конечно, можете сделать именно так, если захотите. И доказательное планирование продолжит работать.

Но вы не обязаны.

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

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

private int width;
public int getWidth () { return width; }
public void setWidth (int _width} { width = _width; }

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

Как бы там ни было, реализация каждого метода доступа занимает у него два часа. Т.е. его оценки времени выполнения задач выглядят следующим образом:

{2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, … }

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

{2, 2, 2, 2, 4, 2, 2, 2, 2, 4, 2, … }

и соответственно скорости

{1, 1, 1, 1, 0.5, 1, 1, 1, 1, 0.5, 1, … }

Теперь подумайте, над тем, что происходит. При моделировании методом Монте-Карло вероятность того, что каждая оценка будет разделена на 0.5 в точности соответствует вероятности, что работа Джона будет прервана начальником. Таким образом, ДП произведет правильное расписание!

На самом деле, ДП, скорее всего, учтет прерывания работы гораздо лучше, чем это сделает самый дотошный разработчик. Как раз поэтому оно так хорошо работает. Вот как я объясняю это людям. Когда программиста прерывают, он становится перед выбором

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

… и в любом случае, ДП даст аналогичные, совершенно точные результаты, вне зависимости от того, с каким типом пассивно-агрессивного разработчика вы имеете дело.

4. Активно управляйте своим проектом


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



Также вы сможете видеть распределение возможных сроков завершения по каждому разработчику:



Некоторые разработчики (как Милтон (Milton) на этом рисунке) могут быть источником проблем из-за того, что их сроки окончания такие неточные: им нужно учиться оценивать затраты для задач лучше. Другие разработчики (как Джейн (Jane)) имеют точную дату завершения, которая, однако, задерживает сдачу проекта — нужно подумать о передаче части их задач другим сотрудникам. Некоторые разработчики (я! ура!) вообще не находятся на критическом пути — их можно оставить в покое.

Границы проекта

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

В идеале нужно предусматривать специальные буферы для всего этого. И правда — добавляйте буферы в свои планы для

  1. Новых идей по функциональности
  2. Ответных действий в конкурентной борьбе
  3. Интеграции (объединение кода, написанного разными разработчиками в одну систему)
  4. Времени на отладку
  5. Тестирования удобства использования (и использования результатов тестирования в конечном продукте)
  6. Бета-тестирования

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

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



На оси X отмечаем дату расчета, Y — дату завершения проекта. На рисунке представлены три кривые: верхняя соответствует результатам с 95% вероятностью, средняя 50% и нижняя — 5%. Чем ближе эти кривые друг к другу, тем более узкий диапазон возможных дат сдачи проекта мы имеем.

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

Кстати

Вот несколько вещей, которые я осознал за годы планирования проектов

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

3. Не позволяйте менеджерам давить на разработчиков с целью сокращения оценок сроков. Часто недостаточно опытные менеджеры программных проектов думают, что смогут «мотивировать» программистов работать быстрее, давая им хорошие, «тугие» (невероятно короткие) планы выполнения задач. Я считаю такой тип мотивации совершенно безмозглым. Когда я не вписываюсь в расписание, я чувствую себя обреченным, угнетенным и лишенным всякой мотивации. Когда же я иду с опережением официального плана, я воодушевлен и продуктивен. Планирование — не место для психологических игр.

Почему менеджеры делают это?

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

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

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

Нельзя получить 4n из n, никак нельзя, и если вы считаете, что вам это удалось, пришлите мне тикер своей компании, и я его сокращу.

интерпретация высказывания про тикер от vmarunin
"… пришлите мне тикер чтобы я мог его зашортить"
Зашортить (открыть короткую позицию) это значит взять в долг акции, продать их, а когда они упадут в цене купить акции и вернуть долг.
Другими словами Джоел готов поставить деньги на то, что если компания может сократить срок разработки с 4n до n, то она обязательно скоро упадёт на бирже.


4. Расписание — это коробка с деревянными блоками. Допустим, у вас есть несколько деревянных блоков, которые не удается поместить в коробку, тогда остается два варианта: взять бОльшую коробку или избавиться от нескольких блоков. Если вы хотите сдать проект за 6 месяцев, а согласно плану работ получается 12, вам остается или отложить дату выпуска, или отказаться от некоторых функций. Нельзя просто так взять и уменьшить деревянный блок.

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

Представьте, что вы придумали две функции. Первая, очень полезная, способна сделать ваш продукт действительно прекрасным. Другая — чрезвычайно простая, и программисты не могут дождаться момента, когда смогут ее закодировать (”Look!&ltblink&gt!”), однако она не несет никакой реальной пользы.

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

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

Когда я работал над Excel 5, наш список планируемой функциональности был огромен, что предвещало очень серьезное отставание от графика выпуска. «Боже мой», — думали мы, — «Это же все очень важные вещи. Как мы будем жить без мастера для редактирования макросов?»

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

Когда Excel 5 приближался к завершению, мы с Эриком Мичелманом ( Eric Michelman) начали работу над спецификацией Excel 6. Мы прошлись по списку функций, которые не успели реализовать в рамках Excel 5. И знаете что? Это был один из самых пошлых списков возможностей, который вы только можете представить. Ни одна из перечисленных в нем функций не заслуживала реализации. Процесс усечения функциональности с целью вписаться в расписание был лучшей услугой проекту, которую мы могли ему оказать. Если бы этого не было сделано, реализация Excel 5 заняла бы в два раза больше времени и наполовину состояла бы из бесполезного дерьма, которое к тому же пришлось бы поддерживать для совместимости до конца времен.

Вывод

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

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


Благодарю truezemez за помощь в переводе названия метода
Tags:
Hubs:
+49
Comments 24
Comments Comments 24

Articles