Текст книги "Экстремальное программирование"
Автор книги: Кент Бек
сообщить о нарушении
Текущая страница: 2 (всего у книги 15 страниц) [доступный отрывок для чтения: 6 страниц]
Часть 1.
Проблема
В данной части книги подготавливается сцена, на которой должно в последующем появиться экстремальное программирование. Здесь описываются различные аспекты проблемы, которую предстоит решить, сформировав новую дисциплину разработки программного обеспечения.
В данной части обсуждаются базовые предположения, которые мы должны учитывать, подбирая методики разработки программного обеспечения, – метафора управления автомобилем, четыре значения, принципы, сформированные на основе этих значений, а также деятельность, которую требуется структурировать в рамках новой дисциплины разработки программного обеспечения.
Глава 1.
Риск: основная проблема
Существующие дисциплины разработки программного обеспечения не срабатывают и не дают желаемого экономического эффекта. Эта проблема обладает огромным экономическим и гуманитарным значением. Мы нуждаемся в новом способе разработки программного обеспечения.
Основная проблема разработки программного обеспечения – это риск.
Вот несколько примеров риска.
• Смещение графиков– наступает день сдачи работы, и вы вынуждены сообщить заказчику, что разрабатываемая система не будет готова еще в течение шести месяцев.
• Закрытие проекта– после нескольких смещений графика и переносов даты сдачи проект закрывается, даже не будучи доведен до стадии опробования в рабочих условиях.
• Система теряет полезность – разработанное программное обеспечение успешно устанавливается в реальной производственной рабочей среде, однако после пары лет использования стоимость внесения в нее изменений и/или количество дефектов увеличиваются настолько, что становится дешевле заменить систему новой разработкой.
• Количество дефектов и недочетов – программная система устанавливается в реальной производственной рабочей среде, однако количество дефектов и недочетов столь велико, что система не используется.
• Несоответствие решаемой проблеме – программная система устанавливается в реальной производственной рабочей среде, однако выясняется, что на самом деле она не решает проблему бизнеса, для решения которой она изначально предназначалась.
• Изменение характера бизнеса – программная система устанавливается в реальной производственной рабочей среде, однако в течение шести последних месяцев проблема, для решения которой предназначалась эта система, потеряла актуальность, а вместо нее бизнес столкнулся с новой, еще более серьезной проблемой.
• Недостаток возможностей – программная система обладает множеством потенциально интересных возможностей, каждую из которых было очень приятно программировать, однако выясняется, что ни одна из этих возможностей не приносит заказчику достаточно много пользы.
• Текучка кадров – в течение двух лет работы все хорошие программисты, работавшие над проектом, один за другим возненавидели разрабатываемую программную систему и ушли на другую работу.
На страницах данной книги вы прочитаете об экстремальном программировании (eXtreme Programming, XP) – дисциплине разработки программного обеспечения, которая ориентирована на снижение степени риска на всех уровнях процесса разработки. ХР способствует существенному увеличению производительности и улучшению качества разрабатываемых программ, кроме того, это весьма занятная практика, доставляющая всем ее участникам массу удовольствия.
Каким образом ХР снижает перечисленные ранее риски?
• Смещение графика – ХР предлагает использовать очень короткие сроки выпуска каждой очередной версии. Предполагается, что каждая очередная готовая к использованию версия системы разрабатывается в течение максимум нескольких месяцев. Таким образом, объем работ в рамках каждой версии ограничен, а значит, если и происходит смещение, оно менее значительное. В рамках каждой версии предусматривается выпуск нескольких итераций запрашиваемых заказчиком возможностей, на разработку каждой из этих итераций уходит от одной до четырех недель. Так обеспечивается гибкая и чуткая обратная связь с заказчиком, благодаря чему он получает представление о текущем ходе работ. В рамках каждой итерации планирование в соответствии с ХР осуществляется в терминах нескольких задач, которые необходимо решить для получения очередной итерации. На решение каждой из задач отводится от одного до трех дней. В результате команда может обнаруживать и устранять проблемы даже в процессе итерации. Наконец, ХР подразумевает, что возможности с наивысшим приоритетом будут реализованы в первую очередь. Таким образом, любые возможности, которые не удалось реализовать в рамках данной очередной версии программного продукта, обладают меньшим приоритетом.
• Закрытие проекта – в рамках ХР заказчик должен определить наименьший допустимый набор возможностей, которыми должна обладать минимальная работоспособная версия программы, имеющая смысл с точки зрения решения бизнес-задач. Таким образом, программистам потребуется приложить минимальное количество усилий для того, чтобы заказчик понял, нужен ли ему этот проект или нет.
• Система теряет полезность – в рамках ХР создается и поддерживается огромное количество тестов, которые запускаются и перезапускаются после внесения в систему любого изменения (несколько раз на дню), благодаря этому удается тщательно следить за качеством разрабатываемой программы. ХР постоянно поддерживает систему в превосходном состоянии. Дефектам просто не дают накапливаться.
• Количество дефектов и недочетов – в рамках ХР разрабатываемая система тестируется как программистами, создающими тесты для каждой отдельной разрабатываемой функции, так и заказчиками, которые создают тесты для каждой отдельной реализованной возможности системы.
• Несоответствие решаемой проблеме – в рамках ХР заказчик является составной частью команды, которая работает над проектом. Спецификация проекта постоянно перерабатывается в течение всего времени работы над проектом, благодаря этому любые уточнения и открытия, о которых заказчик сообщает команде разработчиков, немедленно находят свое отражение в разрабатываемой программе.
• Изменение характера бизнеса – в рамках ХР цикл работы над очередной версией программы существенно укорачивается. Таким образом, ко времени выхода очередной работоспособной версии программного продукта бизнес не успевает претерпеть существенных изменений. В процессе работы над очередной версией заказчик может попросить отказаться от разработки некоторой функциональности и вместо нее добавить в программный продукт другие, совершенно новые возможности. Команда разработчиков даже не обратит внимания на то, работает ли она над реализацией новых программных механизмов, или осуществляется разработка возможностей, определенных еще несколько лет назад.
• Недостаток возможностей – в рамках ХР осуществляется реализация только наиболее высокоприоритетных задач.
• Текучка кадров – ХР предлагает программистам брать на себя ответственность самостоятельно определять объем работы и время, необходимое для выполнения этой работы. Они получают возможность сравнить свои предварительные оценки с тем, что получилось на самом деле. В рамках ХР содержатся правила, определяющие, кто именно имеет право делать предварительные оценки и изменять их.
За счет этого существенно снижается вероятность того, что программист окажется в растерянности перед возложенной на него задачей, которую заведомо невозможно решить. ХР стимулирует интенсивное общение между членами команды разработчиков, снижая ощущение одиночества, которое может возникнуть в случае, если программист не доволен работой, которую он делает. Наконец, в рамках ХР явно определяется модель смены кадров. Новые члены команды постепенно берут на себя все большую и большую ответственность.
В процессе этого они пользуются поддержкой друг друга, а также программистов, которые входят в состав команды уже давно.
Наша цель
Если мы признаем, что риск является основной проблемой, которую требуется решить, то в каком месте следует искать решение этой проблемы? Перед нами стоит задача сформировать стиль разработки программного обеспечения, который позволил бы существенно снизить все перечисленные риски. Кроме того, мы должны как можно понятнее объяснить эту дисциплину программистам, менеджерам и заказчикам. Также мы должны сформировать набор рекомендаций, позволяющих адаптировать данную дисциплину для конкретных локальных условий (другими словами – определить, что в этой дисциплине является незыблемым, а что можно варьировать в зависимости от конкретных обстоятельств).
Именно об этом пойдет речь в первой и второй частях книги. Шаг за шагом мы тщательно изучим каждый из аспектов проблемы, сформируем круг вопросов, на которые нам предстоит найти ответ, а затем мы решим проблему. Мы начнем с рассмотрения базовых предположений, а затем получим решение, которое будет диктовать, каким именно образом должна осуществляться разнообразная деятельность (планирование, тестирование, разработка, дизайн и внедрение), связанная с разработкой программного продукта.
Глава 2.
Эпизод из программистской практики
День за днем программист выполняет одну и ту же последовательность действий, которую можно назвать программным проектом в миниатюре: он изучает задачу, четко связанную с возможностью продукта, в которой нуждается заказчик, затем он формирует набор необходимых тестов, реализует поставленную задачу, вылизывает код, а потом интегрирует его в систему. В каждом таком эпизоде содержатся все этапы, которые обычно составляют процесс разработки крупного программного продукта.
Для начала небольшой экскурс вперед, то есть туда, куда мы с вами движемся. Данная глава описывает живой процесс экстремального программирования так, как это происходит на практике. Речь пойдет об эпизоде разработки. Эпизод разработки – это фрагмент деятельности программиста, когда он реализует некоторую инженерную задачу (наименьший квант планирования) и интегрирует ее с остальной системой.
Я смотрю на мой набор карточек с задачами. На самой верхней из них написано: Экспорт значения квартальных издержек на момент обращения к системе. Я вспоминаю, что на сегодняшнем утреннем совещании ты сообщил присутствующим, что завершил блок вычисления значения квартальных издержек. Я обращаюсь к тебе (моему гипотетическому соратнику) с вопросом, не найдется ли у тебя времени помочь мне с разработкой блока экспорта. Ты отвечаешь: Конечно! Это одно из основных правил ХР: если к тебе обращаются с просьбой о помощи, ты обязан ответить да. Таким образом мы становимся партнерами по программированию в паре.
В течение пары минут мы обсуждаем работу, которую ты выполнил вчера. Ты рассказываешь мне о добавленном тобою в систему коде, о бинарных значениях и о том, как выглядят соответствующие тесты. Мы отодвигаем мой монитор чуть назад, так как при этом эффективность парного программирования несколько увеличивается.
Ты спрашиваешь у меня: Как выглядят тестовые случаи для этой задачи?
Я отвечаю: После выполнения экспортирующего кода значения в экспортированной записи должны соответствовать бинарным значениям.
Ты спрашиваешь: Какие поля требуется заполнить?
Я не знаю, надо спросить у Эдди.
Мы отрываем Эдди от работы на тридцать секунд, и он рассказывает нам о пяти полях, которые связаны с квартальными издержками.
Мы обращаемся к изучению структуры некоторых существующих тестовых случаев, связанных с экспортом. Обнаруживается, что один из тестовых случаев почти полностью нам подходит. Если, используя обнаруженный нами код, создать абстрактный суперкласс, на его основе мы могли бы с легкостью реализовать наш тестовый случай. Так мы выполняем переработку кода (refactoring). Потом мы запускаем существующие тесты, и все они успешно выполняются.
После этого мы обращаем внимание, что несколько других тестовых случаев можно переработать так, чтобы они были основаны на только что созданном нами абстрактном суперклассе. Однако нам необходимо решить стоящую перед нами конкретную задачу, поэтому мы просто берем пустую карточку, записываем на ней выполнить переработку тестовых случаев с использованием класса AbstractExportTest и размещаем эту карточку в наборе задач, которые нам предстоит выполнить.
После этого мы разрабатываем наш тестовый случай. Благодаря тому, что перед этим мы разработали суперкласс, создание нового тестового случая не представляет труда. Мы выполняем эту работу в течение нескольких минут. Где-то в середине работы я говорю: Я уже представляю себе, как мы можем это реализовать. Мы можем...
Однако ты прерываешь меня: Давай сначала завершим работу над тестовым случаем. Пока мы пишем тестовый случай, в голову приходят идеи для трех вариаций. Ты записываешь их на очередной карточке.
Мы завершаем работу над тестовым случаем и запускаем его. Он не срабатывает. Естественно, мы ведь еще ничего не реализовали. Подожди минутку, – говоришь ты, – вчера, когда мы с Ральфом работали над блоком вычислений, мы написали пять тестовых случаев, о которых мы думали, что они не сработали. Все, за исключением одного, сработали с первого раза.
Мы запускаем отладчик и приступаем к изучению работы тестового случая. Мы анализируем объекты, с которыми имеет дело наш тестовый случай.
Я пишу код (или это делаешь ты – все зависит от того, у кого из нас возникнет более удачная идея). Пока мы работаем над реализацией, мы замечаем еще пару дополнительных тестовых случаев, которые неплохо было бы написать. Мы заносим эту информацию на карточку. После того как код реализован, ранее разработанный тестовый случай срабатывает.
Мы переходим ко второму тестовому случаю, затем к третьему. Я реализую их. Ты обращаешь внимание, что код можно упростить. Мне с трудом удается одновременно слушать твои объяснения и продолжать писать код, поэтому я просто передаю тебе клавиатуру. Ты перерабатываешь код, после этого ты запускаешь тестовые случаи и они срабатывают. Ты приступаешь к реализации следующей пары тестовых случаев.
Спустя некоторое время мы смотрим на набор карточек с заданиями, которые необходимо доделать, и обнаруживаем, что нам осталось переделать тестовые случаи, которые были разработаны ранее. Все идет хорошо, и мы переделываем их, а затем убеждаемся в том, что все они срабатывают.
Теперь список дел, которые нам необходимо выполнить, пуст. Мы обращаем внимание на то, что компьютер, на котором выполняется интеграция, свободен. Мы загружаем последнюю версию системы, затем мы загружаем наши последние изменения. Затем мы запускаем все тестовые случаи, потом запускаем новые тестовые случаи, только что разработанные нами, а затем абсолютно все тестовые случаи, которые кто-либо когда-либо разрабатывал. Один из них не срабатывает. Это очень странно, – произносишь ты, – прошло не меньше месяца с тех пор, когда я в последний раз сталкивался со сбоем тестового случая в процессе интеграции. Однако особых проблем в этом нет. Мы отлаживаем тестовый случай и исправляем код. После этого мы вновь запускаем весь полный набор тестов. На этот раз все они срабатывают. Мы включаем наш код в состав системы.
Вот так выглядит полный цикл разработки кода в рамках ХР. Следует обратить внимание на следующие обстоятельства.
• Два программиста работают над решением задачи вместе в одной паре.
• Разработка базируется на тестах. Сначала вы пишете тесты, затем – код. Вы не можете считать работу доделанной до тех пор, пока все тесты не сработают. Если все тесты сработали и вы не в состоянии придумать еще каких-либо других тестов, которые могут не сработать, вы можете считать, что добавление функциональности завершено.
• Пары программистов не только добиваются того, чтобы тестовые случаи срабатывали. Они также выполняют эволюцию дизайна системы. Изменения не ограничиваются какой-то отдельной конкретно очерченной областью. Пары программистов вносят свой вклад в анализ, дизайн, реализацию и тестирование всей системы. Добавление изменений осуществляется тогда, когда система нуждается в этих изменениях.
Сразу же за разработкой следует интеграция, которая включает в себя также интеграционное тестирование.
Глава 3.
Экономика разработки программного обеспечения
Мы должны сделать разработку программного обеспечения экономически более выгодной, для этого мы должны тратить деньги медленнее, приносить прибыль быстрее, а также увеличивать продолжительность эффективного использования разрабатываемого нами программного продукта в реальных промышленных условиях. Но прежде всего мы должны обеспечить более широкую свободу для принятия бизнес-решений[3].
Сложив финансовые потоки, которые втекают в проект и вытекают из проекта, мы можем определить, за счет чего создается экономическая выгода, получаемая от проекта. Приняв во внимание коэффициенты прибыли (процентные ставки), мы можем вычислить чистый текущий объем финансовых потоков. После этого мы можем уточнить результаты нашего анализа, умножив скорректированный с учетом процентных ставок объем финансовых потоков на вероятность того, что проект выживет.
Для создания стратегии максимизации экономической выгоды, связанной с проектом, нам потребуется проанализировать следующие три фактора:
• финансовые потоки, втекающие в проект и вытекающие из проекта;
• коэффициенты прибыли (процентная ставка);
• вероятность того, что проект выживет.
Максимизировать экономическую выгоду можно следующим образом:
• мы можем тратить меньше, однако это достаточно сложно, так как изначально каждый обладает примерно одним и тем же набором знаний и инструментов;
• мы можем зарабатывать больше, однако это возможно только при наличии сверхсовершенной организации маркетинга и продаж, а эти темы в данной книге не обсуждаются (слава богу);
• мы можем тратить средства позже, а получать прибыль раньше, благодаря этому с учетом коэффициентов прибыли нам придется терять меньше за счет процентной ставки на деньгах, которые мы тратим, и получать больше за счет процентной ставки на деньгах, которые мы получаем;
• мы можем увеличить вероятность того, что проект выживет. Таким образом мы с большей долей вероятности получим дополнительные выплаты в процессе дальнейшей работы над проектом.
Варианты
Есть еще один взгляд на экономику программного проекта – это набор вариантов, в соответствии с которыми может развиваться этот проект. Управление программным проектом может осуществляться в соответствии с одним из вариантов.
• Вариант закрыть проект – вы можете получить какую-либо прибыль даже в случае, если работа над проектом будет прервана. Чем большую выгоду вы получите от проекта, который был завершен, не достигнув изначально планировавшегося состояния, тем лучше.
• Вариант смены направления – вы можете изменить направление развития проекта. Стратегия управления проектом будет более выгодной в случае, если в процессе работы над проектом заказчики будут обладать возможностью сменить изначально сформулированные ими требования. Чем чаще это может происходить и чем кардинальнее заказчики могут менять свои требования, тем лучше.
• Вариант отсрочки решения – прежде чем инвестировать средства и ресурсы в том или ином направлении, вы можете подождать до тех пор, пока ситуация сама собой не разрешится и не станет более понятной для вас. Стратегия управления проектом будет более выгодной в случае, если вы будете обладать возможностью подождать с вложением денег, и при этом не потерять полностью возможность инвестирования средств. Чем более длительной может быть отсрочка и чем большее количество денег можно удержать от преждевременного инвестирования, тем лучше.
• Вариант роста инвестиций – если вы видите, что рынок начинает расти, вы можете оперативно увеличить инвестиции для того, чтобы с выгодой воспользоваться этим. Стратегия управления проектом будет более выгодной в случае, если вы будете обладать возможностью все больше и больше расширять производство за счет увеличения объема инвестиций. Чем быстрее и чем дольше проект может расти, тем лучше.
Определение значимости каждого из вариантов – это на две части искусство, на пять частей – математика и на одну часть – старое доброе перетягивание каната.
При этом необходимо учитывать следующие пять факторов:
• объем инвестиций, необходимых для реализации того или иного варианта;
• цена, в рамках которой вы сможете достигнуть цели, если вы будете действовать в рамках того или иного варианта;
• текущая ценность поставленной вами цели;
• время, которое потребуется вам для того, чтобы реализовать тот или иной вариант;
• неопределенность, с которой вы можете оценить ценность поставленной вами цели.
Из всех этих факторов доминирующим как правило оказывается последний: неопределенность. На основании этого мы можем прийти к некоторым выводам и прогнозам относительно разрабатываемой нами стратегии. Представьте, что мы создали стратегию управления проектом, которая максимизирует полезность проекта на основе анализа вариантов и обеспечивает:
• частый возврат точных сведений о текущем состоянии разработки;
• множество возможностей в значительной степени изменить набор изначально заданных требований и направление развития проекта;
• меньший объем изначальных инвестиций;
• возможность при желании увеличить темпы разработки.
Чем большей будет неопределенность, тем полезнее окажется созданная нами стратегия. Это утверждение является справедливым вне зависимости от того, является ли причиной неопределенности технический риск, изменяющиеся условия, в которых функционирует бизнес, или быстро эволюционирующие требования заказчика. (Это является теоретическим ответом на вопрос: Надо ли мне использовать ХР? Использовать ХР следует в условиях, когда требования заказчика неопределенны или быстро меняются.)
Пример
Представьте, что вы занимаетесь программированием фактически в одиночку. Вы видите, что добавление в программу некоторой возможности обойдется вам в $10. Вы ожидаете, что вы сможете заработать на этой возможности приблизительно $15. Таким образом, чистая текущая ценность (Net Present Value, NPV) добавления в программу данной возможности составит $5.
Представьте, что вы не можете сказать точно, какова будет на самом деле ценность рассматриваемой вами возможности, – вы можете лишь предположить, что заказчик будет готов заплатить за нее $15. В действительности этот параметр может отличаться от предполагаемого вами значения на 100% в обе стороны. Теперь предположим, что если вы соберетесь добавлять данную возможность спустя год от текущего момента, то это все равно будет стоить вам те же $10 (см. главу 5).
Какова будет ценность стратегии, в рамках которой вы не будете реализовывать эту возможность прямо сейчас, а подождете в течение года? В настоящее время средняя процентная ставка составляет около 5% годовых. С учетом этой процентной ставки искомая ценность составит около $7,87.
Следовательно, стратегия годичного ожидания, прежде чем добавить в программу новую возможность, обойдется нам дороже, чем если бы мы, ничего не ожидая, прямо сейчас инвестировали деньги в разработку данной возможности (напомню, что на текущий момент соответствующая NVP составляет $5). Почему? В настоящее время мы находимся в неопределенности и не можем точно сказать, будет ли данная возможность действительно полезна для нашего заказчика и сможет ли он прямо сейчас начать зарабатывать на ней деньги. Если мы реализуем возможность прямо сейчас и возможность окажется действительно полезной, то наш заказчик через год получит за счет этого определенную прибыль. Однако может оказаться, что для нашего заказчика эта возможность не представляет никакой ценности, и поэтому, отказавшись на текущий момент от ее реализации, мы можем сэкономить собственные ресурсы.
Говоря проще, варианты помогают нам избавиться от нежелательного риска.