Мифический человеко-месяц или как создаются программные системы
Шрифт:
Рис. 2.2 Зависимость времени от числа занятых — неразделимая задача
Если задачу нельзя разбить на части, поскольку существуют ограничения на последовательность выполнения этапов, то увеличение затрат не оказывает влияния на график (рис. 2.2). Чтобы родить ребенка требуется девять месяцев независимо от того, сколько женщин привлечено к решению данной задачи. Многие задачи программирования относятся к этому типу, поскольку отладка по своей сути носит последовательный
Рис. 2.3 Зависимость времени от числа занятых — разделимая задача, требующая обмена данными
Для задач, которые могут быть разбиты на части, но требуют обмена данными между подзадачами, затраты на обмен данными должны быть добавлены к общему объему необходимых работ. Поэтому достижимый наилучший результат оказывается несколько хуже, чем простое соответствие числа занятых и количества месяцев (рис. 2.3).
Дополнительная нагрузка состоит из двух частей — обучения и обмена данными. Каждого работника нужно обучить технологии, целям проекта, общей стратегии и плану работы. Это обучение нельзя разбить на части, поэтому данная часть затрат изменяется линейно в зависимости от числа занятых.
Рис. 2.4 Зависимость времени от числа занятых — задача со сложными взаимосвязями
С обменом данными дело обстоит хуже. Если все части задания должны быть отдельно скоординированы между собой, то затраты возрастают как n(n-2)/2. Для трех работников требуется втрое больше попарного общения, чем для двух, для четырех — вшестеро. Если помимо этого возникает необходимость в совещаниях трех, четырех и т.д. работников для совместного решения вопросов, положение становится еще хуже. Дополнительные затраты на обмен данными могут полностью обесценить результат дробления исходной задачи и привести к положению, описываемому рисунком 2.4.
Поскольку создание программного продукта является по сути системным проектом — практикой сложных взаимосвязей, затраты на обмен данными велики и быстро начинают преобладать над сокращением сроков, достигаемым в результате разбиения задачи на более мелкие подзадачи. В этом случае привлечение дополнительных работников не сокращает, а удлиняет график работ.
Системное тестирование
Из всех элементов графика работ наибольшему воздействию со стороны ограничений на последовательность выполнения действий подвержены отладка компонентов и системное тестирование. Кроме того, затраты времени зависят от количества выявленных ошибок и от того, насколько они «скрытые». Теоретически, ошибок быть не должно. Из-за своего оптимизма мы обычно склонны недооценивать действительное количество ошибок. Поэтому в программировании придерживаться графиков работ обычно труднее всего при отладке.
В течение ряда лет при планировании разработки программного обеспечения я пользуюсь следующим эмпирическим правилом:
1/3 — планирование,
1/6 — написание программ,
1/4 — тестирование компонентов и предварительное системное тестирование,
1/4 — системное тестирование при наличии всех компонентов.
Это правило имеет несколько важных различий с общепринятым планированием:
1.
2. Половина графика работ, отведенная на отладку законченного кода, значительно выше нормы.
3. Та часть, которую легко оценить, т.е. написание кода, занимает всего одну шестую общего времени.
Изучая проекты, график которых был составлен традиционным образом, я обнаружил, что немногие из них отводили по графику половину времени на отладку, но на практике в большинстве случаев тратили на нее половину фактического времени. Многие проекты укладывались в график на всех этапах, исключая системное тестирование.[2]
Особенно катастрофические последствия может иметь недостаток времени для системного тестирования. Поскольку задержка происходит в конечной части графика, никто не подозревает о том, что график находится под угрозой срыва вплоть до дня сдачи продукта. Плохие вести, полученные поздно и без предупреждения, обескураживают клиентов и менеджеров.
Более того, задержка на этом этапе имеет особенно тяжелые материальные и психологические последствия. Проект осуществляется при полной
укомплектованности работниками и максимальных финансовых издержках. Что важнее, программное обеспечение должно обеспечить поддержку другой деловой активности (поставки компьютеров, запуска новых производственных мощностей и т.п.), и связанные с задержкой вторичные издержки очень высоки. На практике эти вторичные издержки могут быть выше, чем все прочие. Поэтому очень важно в изначальном графике работ отвести достаточно времени для системного тестирования.
Робость в оценках
Для программиста, как и для повара, давление со стороны хозяина может определять запланированный срок завершения задачи, но не может определять время ее фактического завершения. Омлет, обещанный через две минуты, может успешно жариться, но если через две минуты он не готов, то у клиента есть две возможности: ждать еще или съесть его сырым. Тот же выбор встает и перед заказчиком программного обеспечения.
У повара есть еще одна возможность: добавить жару. В результате омлет часто оказывается безнадежно испорченным: горелым с одного края и сырым — с другого.
Я не думаю, что у менеджеров программных продуктов меньше храбрости или твердости, чем у поваров или других менеджеров в инженерных областях. Но липовые графики, нацеленные на желательную хозяину дату, встречаются здесь значительно чаще, чем в любых других инженерных областях. Очень тяжело, рискуя потерять рабочее место, с энергией и любезностью отстаивать срок, который определен без применения каких-либо количественных методов при недостатке данных и подкреплен, в основном, интуицией менеджера.
Очевидно, необходимо сделать две вещи. Мы должны получить и сделать общедоступными численные данные, характеризующие производительность, частоту программных ошибок, методы оценки и т.д. Вся отрасль может только выиграть от опубликования таких данных.
Пока методы оценивания не получат более прочной основы, менеджерам остается только мужаться и защищать свои прогнозы, утверждая, что полагаться на их слабую интуицию все же лучше, чем основываться на одних желаниях.
Действия при срыве графика