Особенности разработки ПО

Особенности разработки ПО

Обратимся к тем разделам нашей науки, для которых одних лишь общих правил менеджмента недостаточно.
В главе 5 «Самое важное» я говорю о самом важном для успеха программного проекта понятии - об итеративной разработке. Оказывается, главнейший фактор своевременной поставки качественного программного продукта следующий: может ли команда эффективно применять итеративную разработку?.
В главе 6 «Моделирование» обсуждается один из новых инструментов, позволивших поднять уровень абстракции и лучше объяснить суть ПО. Недостаток этого направления - некоторая недооценка написания кода, чем программисты заняты большую часть своего времени.
Поэтому в главе 7 «Кодирование» я кратко рассказываю о языках программирования и том, как разработчикам и менеджерам приспособиться к появлению «идеального языка», регулярно происходящему примерно раз в 10 лет.
Наконец, в главе 8 «За дверь его!» я отмечаю, что успеху продукта должна предшествовать его поставка, а те продукты, которые разрабатываются вечно, редко оказываются прибыльными. Но оказывается, что «избавиться» от продукта не так просто, как может показаться. Я даю несколько советов тем, кто еще не освоил эту «досадную», но важную часть нашего дела.
Самое важное.
В этой главе вам предстоят два знакомства. Первое - с понятием итеративной разработки, а второе - с персонажем по имени Роско Леруа.
Итеративная разработка.
Размышления о том, почему программные проекты заканчиваются успехом или провалом, многое помогли понять тем, кто занят в индустрии ПО. Из всех концепций, появившихся за последние 20 лет, итеративная разработка далеко опережает по важности остальные. Помимо очевидного закона, гласящего, что нельзя разработать очень хорошую систему, имея посредственных работников, важнейшее методическое соображение касается способа разработки ПО. Я многократно замечал, что команды, практикующие итеративную разработку, чаще добиваются успеха, тогда как те, которые применяют другие методы, чаще подвержены неудачам. Из методов успешной работы, пропагандируемых Rational Software, самым важным, по моему мнению, является итеративная разработка.
Чем это вызвано?.
Основатели метода итеративной разработки отказались от чрезмерно жесткого водопадного (последовательного) подхода (waterfall approach), который доминировал в крупных проектах восьмидесятых годов. В его основе лежат снижение риска, инкрементное построение и оценка сделанной работы по реально работающему коду, а не по документам. Подробнее.
об итеративной разработке можно прочесть у Ройса
или Кролла и Крухтена.
В данной главе я рассказываю о некоторых технических причинах, по которым итеративная разработка постоянно доказывает свое превосходство. Но еще важнее, что здесь обсуждаются доводы в ее пользу, относящиеся к управлению. Это должно устранить разрыв между менеджером программной разработки и его менеджером, и вот что я имею здесь в виду. Итеративная разработка возникла в программных проектах и является их уникальной особенностью. Многим менеджерам общего профиля привычнее иметь дело с последовательным подходом, более близким к классическим методам управления проектами, с которыми они знакомы. Поэтому для данной главы возможны два способа употребления:.
• Менеджер программной разработки может дать ее почитать своему менеджеру, которому станет легче понять, как осуществляется управление данным проектом.
• Главный менеджер может дать почитать ее своему менеджеру, руководящему программной разработкой, если тот не применяет итеративную разработку. При этом возникает вопрос, почему он так поступает.
В обоих случаях эта глава может послужить стартовой площадкой для разговора о том, как в данном проекте будут происходить управление, контроль и доклад руководству. Все это полезно обсудить раньше, чем начнется осуществление проекта, поскольку легче будет установить правила взаимоотношений между менеджером программных разработок и его менеджером. Это необходимое действие наряду с утверждением бюджета и подбором команды.
Роско Леруа.
Первое, что вы должны усвоить: не стоит смеяться над именем Роско. «Оно показывает, что у моих родителей было чувство юмора. Кроме того, - добавляет он всегда, - могло быть и хуже, например, назови они меня Леруа Леруа».
Роско - старый боевой товарищ моего отца. По словам Роско, они оба служили под командованием Паттона, хотя я подозреваю, что Роско был непосредственным начальником отца, а Паттон находился где-то значительно выше. Роско один из тех старых морских волков, у которых есть свое мнение практически по любому вопросу. Неприятно то, что обычно он оказывается прав. Конечно, когда он неправ, это приводит к плачевным результатам, потому что он держится за свои убеждения до самого конца. Однажды я видел, как Роско выложил в покере все свои фишки на середину стола, будучи уверен, что его карты лучше, чем у остальных. Результаты были примечательны, но не совсем в том смысле, в каком хотелось бы Роско.
Его житейская мудрость проста и понятна. Она выражается в форме освященного временем совета: не лезь глубоко в теорию, и все будет в порядке. Поступать, как Роско, - это значит положиться на веру, что всегда полезно, когда настает решающий момент. Рассказывая, как он и там-то был, и тем-то занимался, он похваляется, что кончил всего восемь классов, но у меня есть все основания полагать, что где-то в тридцатых годах он окончил прекрасную школу. Отец объяснил мне это расхождение тем, что Роско просто не чувствует необходимости хвастать своим образованием.
Роско служил в армии, тушил пожары на нефтяных скважинах с Boots & Coots и работал горным инженером. Такой опыт сделал из него прагматика, но также научил действовать в жестких условиях. Если вы пригласите его на обед, то грязь из-под ногтей он вычистит, но не рассчитывайте, что он выберет правильную вилку.
Роско не прибегает к сложной математике, ему хватает арифметики. Обычно его ответы выражаются целыми числами. Если поинтересоваться у него, почему это так, он ответит примерно так: «Ну, в конечном счете все сводится к тому, сколько понадобится динамитных шашек и сколько человек для расчистки обломков. Но я же не буду распиливать шашки пополам и дробное количество людей тоже не стану нанимать на работу!». После такой формулировки ясно, что с высшей математикой покончено.
У Роско хорошая подготовка, твердые ценности и тьма опыта. Менеджер общего профиля из него замечательный. С точки зрения нашего повествования единственный его недостаток - это слабое представление о программировании.
Будем считать это не «изъяном», а характерной особенностью. Несколько лет назад, когда закрылась его шахта, Роско решил попробовать свои силы в разработке программ. Я взял на себя труд просветить его в этом деле, но, разумеется, он изрядное время занимался просвещением меня.
Оставляем последовательный подход.
Как-то раз мы с Роско шли по его двору, собираясь поиграть в «подковки». Я сказал, что не играл несколько лет, но уверен, что обыграю его. «OK, посмотрим, сынок, кто кого побьет, - сказал Роско. - Но прежде чем учить тебя, как правильно бросать подкову, я покажу, почему последовательная разработка обречена на провал».
Я невольно улыбнулся. Примерно за полгода до этого о разработке программ хотел поговорить я. Теперь уже Роско поднимал эту тему. Я не устаю искать новые идеи и очень заинтересовался, что же он мне расскажет.
Подобрав себе пару подков, я вдруг почувствовал, что эти крупные штуковины в форме буквы «омега» оказались тяжелее, чем мне представлялось. «Ну, давай, - скомандовал Роско. - Вот столб. Посмотрим, попадешь ли ты с первого броска».
Естественно, после своей похвальбы я чувствовал себя несколько неловко. Я сделал несколько пробных взмахов, приноравливаясь к подкове, и бросил ее. Конечно, на столб подкова не попала, даже намека на это не было. Она просто отскочила и приземлилась метрах в 5 от цели.
- Так нечестно! - возмутился я. - Ты должен был дать мне несколько пробных бросков.
Для тех, кто не знаком с этой игрой, надо сказать, что обычно перед началом соревнований делают несколько тренировочных бросков. То же бывает в любом деле. Необходимо приспособиться к своему снаряжению, которым в данном случае была моя рука, давно не практиковавшаяся. «Что ж, сказал Роско, - это вряд ли помогло бы тебе, потому что есть три причины, по которым ты проиграл. Во-первых, как ты видишь, цель оказалась не там, где ее ожидала твоя рука, из-за некоторых ошибок калибровки.
Во-вторых, исполнение никогда не бывает совершенным; никто не бывает абсолютно постоянным - подкова не всегда летит туда, куда мы целимся. И, втретьих, в промежутке между тем, как ты послал подкову и моментом ее падения на землю столбик переместился!».
- Чушь, - сказал я, - никто столбики не двигал.
- Отчасти верно, но после того, как ты бросил подкову, налетел порыв бокового ветра со скоростью 40 миль в час, который ты не учел. Эффект был таким же, как если бы кто-то переместил столбик в противоположном направлении, - ответил Роско. - Кроме того, угловое отклонение нужно помножить на расстояние, которое предстоит пролететь подкове, поэтому неудивительно, что ты промазал.
- Чем хорошо управление проектами - не обязательно каждый раз точно попадать, - сказал я.
- Это верно, - ответил Роско. - Потому и говорят, что «чуть-чуть не попал» засчитывается только тогда, когда бросаешь подкову или гранату. «Достаточной близости» часто оказывается достаточно при управлении проектом. Действительно плохо бывает тогда, когда промах оказывается большим, особенно, если твоя «подкова» летела долго. А при последовательном подходе такое происходит сплошь и рядом, потому что бросок у тебя всего один. При этом обычно, как и в «подковках», вмешиваются три важных фактора:.
• Цель оказывается не там, где ты рассчитывал.
• Во время работы люди совершают ошибки.
• Вдобавок ко всему цель движется.
Это выглядело разумным. Соглашаться, что попытка будет единственной, видимо, глупо. Но я решил подразнить Роско, выступив с совершенно противоположных позиций.
Другая крайность.
- Хорошо, я тебя понял. Давай попробуем забыть вообще о планировании и будем просто непрерывно уточнять свое местонахождение и направление дальнейшего движения, - мило улыбнулся я.
- Не шути, сынок, - ответил Роско. - Мы оба знаем, что анархия тоже неэффективна. Она просто влечет бессмысленное реагирование на малозначительные события. По-моему, у вас, физиков, это называется броуновским движением. Бурная активность и слабый прогресс. Главная проблема вот в чем: любой проект должен осуществляться в виде последовательности этапов. И самое важное - это решить, насколько продолжительным лучше всего сделать каждый этап и сколько таких этапов должно быть.
Ясно было, что он готов к большому выступлению, и я хотел послушать его, поэтому я сказал: «OK, Роско, то, к чему ты ведешь, куда интереснее, чем „подковки“, да и рука у меня побаливает. Сделаем перерыв».
Роско милостиво согласился.
- Да, выпьем по чашечке кофе, и я расскажу тебе о «коротких векторах», сказал Роско. - А пока мы будем разговаривать, я сделаю для тебя несколько рисунков.
Итак, мы побрели к дому, налили себе кофе (кофеварка работает у Роско весь день) и перешли на заднюю террасу.
Первый рисунок Роско.
Как только мы уселись в пару старых кресел-качалок, Роско вытащил из кармана огрызок карандаша и изобразил на бумажной салфетке то, что вы можете увидеть на рис. 5.1.
- Из геометрии нам известно, что в идеале кратчайшим путем между началом и концом проекта («целью») служит пунктирная линия, которую я только что провел. Те, кто придерживается последовательного способа, тешат себя иллюзией, что могут пройти по этому пути, но мы только что видели три причины, по которым это невозможно. Действительно хоро-
Рис. 5.1. Первый рисунок Роско - короткие векторы.
ший менеджер проекта идет другим путем, типа того, который я нарисовал: из S1 в S2, оттуда в S3 и т. д. - делая ряд маленьких шагов, которые приводят к конечному результату. Каждый из этих шагов я называю вектором так говорят на своем жаргоне авиадиспетчеры. У вас, программистов, каждый такой шаг называется итерацией.
- Напоминает парусник, лавирующий против ветра, - заметил я.
- Весьма, но останемся пока на позициях геометрии. Я хочу сравнить этот маршрут с тем, которым пошел бы менеджер проекта, если бы собрался обойтись всего двумя или тремя итерациями. - Роско глотнул кофе и взял другую салфетку.
Второй рисунок Роско.
- Вот маршрут, который выбрал бы такой менеджер, - сказал он, нарисовав рис. 5.2.
- Обрати внимание, что здесь мы опять сделали упрощающее предположение, что цель не перемещается, хотя мы знаем, что это не так, - добавил он.
Я сразу заметил, что L1 идет в том же неверном направлении, что и S1 на предыдущем чертеже, и обратил на это внимание Роско. «Разумеется,
Рис. 5.2. Второй рисунок Роско - длинные векторы.
они оба плохо начинают из-за ошибок прицеливания и исполнения. Но обрати внимание, что м-р Длинный Вектор остается на ложном пути гораздо дольше».
Кроме того, в первой точке, где производилась коррекция, оба менеджера - м-р Короткий Вектор и м-р Длинный Вектор - одинаково неправильно угадали направление дальнейшего движения: L2 и S2 направлены примерно одинаково. И снова м-р Длинный Вектор слишком долго упорствовал, прежде чем поменять направление.
«Теперь давай измерим длину всех трех маршрутов, - сказал Роско. Пунктирная линия оказалась длиной 10 дюймов. Так... L1-L2-L3 протянулась примерно на 15 дюймов. А S1-S2-S3-S4-S5-S6-S7 - примерно на 12. Итак, м-р Короткий Вектор на 20% длиннее оптимальной величины, а м-р Длинный Вектор - на 50% длиннее».
Минуточку!.
У меня возникло подозрение. «Постой, Роско! - вскричал я. - Я могу нарисовать для м-ра Длинный Вектор такой путь, который будет не длиннее, чем у м-ра Короткий Вектор».
- Верно, - ответил Роско. - С геометрической точки зрения совсем не обязательно, чтобы у м-ра Короткий Вектор всегда оказывался более короткий маршрут. Если мистеру Длинному повезет, то его результат окажется лучше. Но на практике все не так. Статистически усредняя многочисленные проекты того и другого, мы видим, что проекты м-ра Короткий Вектор оказываются эффективнее. Причина в том, что короткие векторы позволяют делать ряд других вещей, обычно невозможных при длинных векторах. Через минуту мы поговорим об этом. Ты прав, что нет геометрического доказательства данного обстоятельства, этот факт эмпирический, и все же геометрическая аналогия во многом склоняет в его пользу.
Я уже готов был принять рассуждения Роско, когда он вернулся к прежней точке зрения: «Ни один из этих рисунков не учитывает третьего фактора: вы стремитесь к цели, которая не стоит на месте. В отличие от столбика для набрасывания подков, в реальном мире цели всегда движутся. Это означает, что м-р Длинный Вектор рискует гораздо больше, чем м-р Короткий Вектор, потому что последний прицеливается чаще. Когда цель смещается, он меняет направление, а потому меньше времени тратит на движение по неверному пути».
Укорачиваем векторы.
«Итак, - сказал Роско, - продолжим наш анализ. По нашей геометрической аналогии, если время и ресурсы пропорциональны длине пути, то м-ру Короткому Вектору потребуется их только на 20% больше, чем минимально нужно для успеха, тогда как м-ру Длинному Вектору нужно на 50% больше минимума. Поэтому у м-ра Короткого Вектора гораздо больше допустимая ошибка.
Можно взглянуть на это иначе, если посчитать объем отходов и переработки. Из 12 единиц, использованных м-ром Коротким Вектором, 10 нужны для конечного результата, а 2 потрачены напрасно, поэтому в отходы и переработку у него пошло около 16% всех затрат. У м-ра Длинного Вектора впустую потрачены 5 единиц из 15, поэтому у него отходы и переработка составляют 33%. Если пользоваться такой метрикой эффективности, то м-р Длинный Вектор действует вдвое хуже, чем Короткий».
Слова Роско были весьма убедительны. «Хорошо, Роско, - сдался я, похоже, что короткие векторы представляют собой хороший универсальный принцип управления проектами. Но почему эта идея еще важнее в программных проектах?».
«С удовольствием объясню тебе, сынок, - сказал Роско торжествующе. Но не принесешь ли ты нам сначала еще по чашечке кофе?» Затем он закурил свою любимую «стоджи».
Применение к разработке ПО.
Когда я вернулся с кофе, Роско сделал глубокую затяжку и продолжил свои рассуждения. «Я считаю, - сказал он, - что для программных проектов обычно характерны следующие черты:.
• Ресурсы очень ограниченны; допустимая погрешность всегда очень мала.
• Вначале очень трудно точно «прицелиться»; как и в «подковках», нужно подобрать замах и начальную скорость. Можно сказать и подругому: обычно вначале технические требования малопонятны.
• Ошибки исполнения неизбежны, особенно в начале.
• Цель всегда смещается по ходу проекта.
• Слишком большая задержка на неверном пути обычно оказывается катастрофической: приходится выбрасывать работу, которая считалась «выполненной», и начинать все сначала.
Если принять во внимание все эти особенности, то итеративный подход с короткими векторами начинает выглядеть очень привлекательно».
Аргументация показалась убедительной. Ясно было, что ошибки, особенно на ранних итерациях, могут оказать очень большое влияние, если их не обнаружить и не исправить. Когда я сообщил об этом Роско, он многозначительно кивнул.
Обучение на практике и выбор коротких векторов.
- Ты не так глуп, как может показаться, - заметил он. - Работа должна совершаться короткими векторами, чтобы вся команда знала, как идут дела, и проводила соответствующие изменения курса. Накопив достаточно знаний и перенастраивая соответственно свои механизмы, ты совершаешь менее значительные ошибки в «прицеливании». С каждой очередной итерацией ты можешь действовать успешнее, исходя из того, что стало известно, поэтому все меньше отклоняешься от выбранного пути. И каждый раз, соединяя новые знания с обнаружением перемещения цели, ты можешь лучше предсказывать движение в будущем. Можно даже наловчиться и немного «упреждать» цель. Следовательно, метод коротких векторов приводит к укорочению суммарного пути по двум причинам. Во-первых, меньше времени тратится на ошибочные направления в начале пути (принцип коротких векторов). Во-вторых, последующие векторы становятся ближе к оптимальным (принцип обучения). Хотя и бывают счастливые исключения, но статистически именно эти две особенности ответственны за более короткий суммарный путь, если сделать усреднение по большому числу проектов.
«Есть ли систематическая технология максимально эффективного обучения на ранних итерациях?» - подумал я вслух.
Программирование рисков.
- Да, и она называется программированием рисков, - ответил Роско. Программирование рисков занимается выявлением опасных мест проекта. Допустим, что мы применяем абсолютно новую технологию. Она может увести наш вектор в совершенно неверном направлении, поскольку если эта технология окажется непригодной, мы потратим на нее массу времени, а в итоге откажемся от нее и выберем другую. Посмотрим, как можно разобраться с ней на ранних итерациях.
Роско стал излагать.
- Определив, что применение этой новой технологии связано с риском, мы должны расположить ее соответственно величине опасности в перечне других рисков проекта. Допустим, что она займет в этом списке первое место. Что мы делаем дальше?.
- Опыт разработки программного обеспечения подсказывает мне ответ, - произнес я. - Сначала нужно устранить или снизить в следующей итерации риск применения именно этой новой технологии. Но согласно твоему принципу коротких векторов нам следует ограничить сферу действия каждой итерации. И поэтому спроектировать часть системы так, чтобы «выдавить» эту новую технологию как можно быстрее и как можно тщательнее. Мы должны принять решение, причем обоснованно и быстро. Итерации надо проектировать примерно так же, как научный эксперимент: что мы хотим установить? как мы это установим? как сделать это с минимальными побочными эффектами?.
- Даже я не сказал бы лучше, - согласился со мной Роско. - А что ты ответишь тем, кто скажет, что это уже не итеративная разработка, а создание прототипа?.
- Конечно, это несколько напоминает создание прототипа, - продолжал я. - Но есть одно важное отличие: мы должны проверить технологию в контексте того, как она будет действовать в итоге в окончательном продукте, поэтому нужно также учесть масштабируемость и производительность. Экспериментировать на этой стадии с игрушками опасно, поскольку может возникнуть ложное чувство безопасности и самоуспокоенности. Хорошо спланированные итерации приведут к построению части системы, которое подтвердит или отвергнет применимость этой технологии. В конце итерации должна быть возможность оценить работающую программу и ответить на простой вопрос: продолжать двигаться в этом направлении или нет. Если да, то созданное во время этой итерации войдет в окончательный продукт, в отличие от прототипа, который будет выброшен.
Подытоживая, я добавил: «Предпочтительнее тот эксперимент, который может показать непригодность новой технологии, а не тот, который усыпит наши подозрения относительно нее. Иногда, уступая желанию выбрать определенный путь - в данном случае это применение новой технологии, мы планируем такие итерации или эксперименты, которые успокоят нашу тревогу. В результате в будущем нас могут ожидать большие неприятности, если обнаружится, что мы принимали желаемое за действительное».
- Да, - сказал Роско, - есть добрый совет: проявить жесткость в начале, чтобы не случилась беда позднее.
Программирование риска дает нам цель для каждой итерации. Итерация может быть нацелена на проверку нескольких рисков, но всегда нужно разбираться с ними в порядке очередности. И помни, что чем раньше начинаешь работать над сложными проблемами, тем больше времени останется на их решение, - продолжал он. В связи с этим я вспоминаю одну очень неприятную ловушку, в которую на моих глазах попадали многие проекты ПО.
Я был весь нетерпение.
А эту песню ты слышал?.
- Иногда я слышу, как менеджеры программных проектов говорят: к этому риску мы обратимся позднее, а пока займемся простыми вещами, и у нас будет время подумать. Когда я слышу такое, у меня давление подымается выше крыши! - воскликнул Роско.
- Ну, Роско, я знаю, откуда идет такой способ мышления, - сказал я. Мы же сами предлагаем его своим студентам для решения контрольных заданий в условиях дефицита времени. Мы всегда предупреждаем их, что лучше сначала сделать простые задания, «поместить деньги в банк», а оставшееся в конце время посвятить сложным задачам. Логика в том, чтобы получить побольше баллов за то, что ты знаешь, а не «оставлять деньги на столе» из-за того, что не хватило времени.
Роско на время задумался.
- Пожалуй, в каких-то обстоятельствах такую стратегию можно оправдать. Но дело в том, что у программных проектов есть свои особенности. Ты не получишь никаких баллов за незавершенный проект, как можно получить их за частично выполненную контрольную. Реализуя проект, ты обязан решить сложные задачи. Поэтому ситуация не просто непохожа, она диаметрально противоположна.
Я согласился.
- Стало быть, Роско, ты утверждаешь, что надежда на то, что команда станет работать над трудными или рискованными задачами в фоновом режиме, - это лишь бесплодная мечтательность, и вот почему:.
• Пока команда работает над «простыми вещами», она не станет размышлять о рисках, отложенных на будущее. Команде трудно сосредоточиться одновременно на нескольких проблемах, и, начав работать над простой задачей, она совершенно забудет об отложенной задаче, связанной с риском. С глаз долой - из сердца вон.
• Согласно закону Паркинсона «легкая задача» неизбежно разрастется вширь, чтобы занять собой весь график работ. При этом более трудные задачи вытесняются. Я не раз был свидетелем такого хода событий. Потратив на 20-30% больше времени, чем предполагалось, на легкие задачи - иногда из-за чрезмерного перфекционизма - команда уже начинает отставать от графика. Вот тут она и сталкивается с настоящими трудностями. При этом проблема была известна давно. Она же не исчезла оттого, что ее игнорировали.
• В конечном итоге у команды оказывается меньше времени для работы над сложной проблемой, а не больше.
• И вот худшее, что может произойти: иногда для решения сложной проблемы приходится выкинуть все, что вы сделали, занимаясь «легкой задачей», и начать все сначала.
И в заключение я подвел итоги.
- Мораль сей истории: определите приоритет своих рисков и начните с самого опасного. Если в результате не останется времени на решение «простых задач», значит, вы в любом случае были обречены на провал.
- Вот теперь, сынок, ты попал в точку, - сказал Роско и дополнил мое наблюдение еще одним убедительным своим. - Если бы я выбился из графика, то мне было бы гораздо легче пойти к боссу и попросить у него дополнительное время, сумей я доказать ему, что моя команда работает по плану, который уже позволил, исключить большинство рисков. Напротив, если бы мне пришлось признаться, что мы не только отстали от графика, но нам еще предстоит разобраться с некоторыми проблемами, связанными с высоким риском, то мои позиции оказались бы очень слабыми. Вполне возможно, что мне не дали бы дополнительного времени, а проект бы закрыли. И, вероятно, были бы правы.
Еще об обучении на практике.
Со всем этим я был вполне согласен: короткие векторы, целевое определение рисков и первоочередное обращение к сложным задачам. Одно мне не давало покоя: в итеративной разработке мы обязаны не только попутно учиться, но и применять то, чему научились.
Я обратил внимание Роско на то, что нельзя планировать следующую итерацию, пока не применено то, чему мы научились на предыдущей. В итеративной разработке нет места «автопилоту»: нельзя спать, когда меняется курс. В известном смысле итеративная разработка не только поощряет применение полученных знаний, но просто требует этого.
- Сравни это с организациями, которые не применяют итеративную разработку, - сказал Роско. - Часто ли приходилось тебе слышать, как люди говорили: «Ну уж в следующем проекте я такой ошибки не сделаю» или «Придется запомнить это на будущее»? Так происходит потому, что их план проекта настолько жесткий, что сразу учесть в нем полученные уроки они не могут. У них есть «зафиксированный» план, изменить который нельзя или очень трудно. Это печально по двум причинам: во-первых, команда смирилась с тем, чтобы «погибнуть вместе с кораблем», поскольку считает, что «слишком поздно» менять план; во-вторых, этот урок скорее всего будет забыт, когда появится новый проект, и весьма вероятно, что те же ошибки будут повторены вновь.
Вена на виске у Роско забилась, и я понял, что близится крещендо. - Это и есть «планирование, вышедшее из-под контроля», - воскликнул он. - Это все равно, что путать карту с местностью. Или объяснять провал плохими инструментами. Если действующий план ведет к катастрофе, МЕНЯЙТЕ ЭТОТ ПЛАН!!! - Он откинулся в своем кресле.
Я вынужден был согласиться. Итеративная разработка требует немедленно применять уроки, извлеченные из этого проекта, ко всем последующим итерациям того же проекта. Как объяснит вам любой преподаватель, обучение наиболее продуктивно и полезно, если как можно скорее применять полученные уроки. Это очень важное различие между итеративной и последовательной разработкой. Итеративная разработка требует «ковать железо, пока оно горячо», даже если это сопряжено с болью: если применить правильную технологию, пока боль еще свежа, урок окажется глубже и вернее.
Следствия для бизнеса.
Роско хотел сделать еще одно замечание. Он снова потянулся за салфетками и вытащил новый «холст» для своего завершающего эскиза.
- Ты наверняка видел вот такие кривые, сравнивающие каскадную (последовательную) и итеративную разработку, - произнес он, вычерчивая рис. 5.3.
Время Время.
Рис. 5.3. Третий рисунок Роско - каскадная разработка против итеративной
Водопадный процесс Итеративный процесс.
- Основной смысл этих кривых в том, чтобы показать, что при каскадной разработке риски сохраняются гораздо дольше, поскольку, пока система не будет в достаточной мере собрана, мы не сможем узнать, как в действительности обстоят дела. При итеративной разработке, которая предполагает целевое обнаружение рисков, компоновку и сборку в достаточном объеме с первой же итерации, риски устраняются на ранних стадиях. На обоих рисунках точка «D» представляет собой момент принятия решения о продолжении или прекращении проекта. То есть если в какой-то момент кривая риска не пойдет резко вниз, мы можем решить, что продолжение невозможно; без сокращения риска проекта дальнейшие инвестиции в него невозможны или нецелесообразны.
- Конечно, Роско, - сказал я. - Я видел, как Дэйв Бернштейн
годами рисует эти кривые. Ничего нового тут нет. Ясно, что лучше принять решение раньше, чем позже. Поэтому последовательный подход уступает по качеству.
- Да, - возразил Роско, - но есть второе, менее известное обстоятельство, также свидетельствующее в пользу итеративной разработки. Я тебе сейчас его продемонстрирую.
Эффект численности персонала.
т~ч оско взял карандаш.
- Наложим на наши картинки кривую численности сотрудников. При последовательной разработке сотрудники принимаются на ранних стадиях, тогда как в итеративных проектах это происходит позже. Маленькие отборные команды, способные быстро продвигаться вперед, идеально подходят для выполнения основных работ на ранних этапах, т. е. на итерациях обследования и проработки.
Затем, на стадиях построения системы и передачи в эксплуатацию, добавляется много новых людей. Разница выглядит примерно так. - И он нарисовал новые кривые ( рис. 5.4).
- Теперь допустим, что наш проект закрывается в точке D на обеих кривых. Ресурсы, израсходованные к этому моменту, показаны в виде заштрихованных областей под кривыми - площадями по кривой численности персонала от начальной точки до точки D, в которой происходит закрытие проекта. - Заштрихованные им области показаны на рис. 5.5.
- Сравни заштрихованные области. Итеративный сценарий предпочтительнее по двум причинам: решение о закрытии проекта принимается раньше, а затрат произведено гораздо меньше, поскольку проект начинался с малой численностью работников с намерением увеличить ее позднее.
Роско был прав, но мне хотелось бы отметить одну маленькую деталь. При итеративной разработке в начале проекта участвует гораздо меньше сотрудников, чем при последовательном методе, но обычно это более
Рис. 5.5. Третий рисунок Роско - последовательный метод против итеративного, дополненный заштрихованной областью
Рис. 5.4. Третий рисунок Роско - последовательный метод против итеративного, дополненный графиком численности персонала
Время Время
Водопадный процесс Итеративный процесс.
опытные,
а потому высокооплачиваемые работники. Поэтому заштрихованные области отражают численность персонала, но необязательно затраты на оплату его труда. Но обычно данный эффект не столь существенен, поскольку большее значение имеет разница в численности занятых.
Роско продолжил рассуждения.
- Отсюда можно сделать вывод, что появляется возможность начинать больше проектов с итеративной разработкой, потому что можно быстро прекращать их, неся относительно небольшие убытки. Хотя выгода от этого не столь высока, поскольку в большинстве организаций не так много действительно ценных работников, которых можно было бы использовать на ранних итерациях. Таких людей всегда не хватает.
Роско близился к завершению своего рассказа.
- Запомни также, что последовательный способ - это катастрофа, потому что с увеличением расходов на заработную плату (заштрихованной области) организационно и политически становится все труднее закрыть проект. Когда проект с итеративной разработкой закрывается на раннем этапе, трудоустроить нужно относительно небольшое число людей. Когда же закрывается последовательный проект на поздней стадии, это влечет перемещение многих людей.
Я понял его мысль. В конечном итоге, когда по какой-то причине приходится прекратить работу над проектом, с деловой точки зрения лучше сделать это раньше, прежде чем будут впустую истрачены существенные средства. Способ комплектации персоналом при итеративном подходе снижает эти расходы на начальных этапах до минимума.
Простой здравый смысл.
Часто аргументация в пользу итеративной разработки бывает сосредоточена на «технологии» разработки ПО. Указывают на такие проблемы, как необходимость проведения исследований, неточность выдвигаемых требований, риски архитектуры, производительности, интеграции и т. д., которые оправдывают итеративность разработки.
Роско же продемонстрировал мне, что итеративная разработка оправданна с общей точки зрения управления проектами. Но в частном случае некоторые особенности, присущие разработке программных систем, еще более усиливают преимущества коротких векторов, первоочередного анализа рисков и применения полученных знаний. Таким образом, то, что полезно в общем случае, оказывается еще полезнее, когда в проекте создается ПО. Кроме того, разумная политика комплектования персоналом на ранних итерациях гарантирует, что, даже если проект придется закрыть, финансовые потери окажутся не слишком большими.
Как сказал Роско, погасив свою сигару и закинув ноги на перила террасы, «если это оправданно с точки зрения технологии и с точки зрения бизнеса, то это оправданно и для меня».
Резюме.
Существует довольно широко распространенное мнение, что критиковать последовательный подход - это все равно что избивать мертвую (или не родившуюся) лошадь. Вопреки расхожему мнению последовательный подход, так сказать, жив и невредим и продолжает по сей день губить проекты. В разработке ПО от него отходят гораздо медленнее, чем хотелось бы.
В своей книге об управлении проектами Уокер Ройс указывает, что его отец, Уин Ройс, предлагал использовать последовательный подход гораздо более итеративным образом, чем это стали делать на практике. Очевидно, путаница существует даже в этом вопросе.
Вместо того чтобы обсуждать недостатки последовательного метода, гораздо более конструктивно, по моему мнению, сосредоточиться на полезных рекомендациях для итеративного:.
• Уделите особое внимание архитектуре;.
• Учитесь на ранних этапах, и это приведет к последующему росту эффективности;.
• Последовательно и пошагово наращивайте систему с каждой итерацией;.
• Судите о прогрессе по работающему коду, а не по документам;.
• Тестируйте, соединяйте компоненты и выполняйте сборку на каждой итерации;.
• Неуклонно снижайте риск, решая в первую очередь сложные задачи;.
• Корректируйте план, тщательно изучая результаты предыдущей итерации;.
Если у вас остались сомнения в отношении итеративной разработки, я могу только посоветовать вам найти менеджера, которому довелось применять оба подхода, и потолковать с ним. Дальнейшее изложение предполагает, что вы приняли на вооружение итеративный метод разработки ПО. С ним тесно связано и множество других концепций, которые я буду обсуждать. Например, я поведу речь о рабочей среде с «максимальным доверием», которая важна для эффективного применения итеративного метода. Еще одна близкая идея - это стабильная базовая «программная архитектура», благодаря которой в случае применения итеративного метода можно удерживать на правильном курсе сложный проект. Лучше всего описать эту архитектуру с помощью модели, поэтому следующую главу я посвящу моделированию.