Кент Бек
Экстремальное программирование
Аннотация
Эта книга об экстремальном программировании. Экстремальное программирование, часто обозначаемое аббревиатурой «XP» – это упрощенная методика организации производства для небольших и средних по размеру команд разработчиков, занимающихся разработкой программного продукта в условиях неясных или быстро меняющихся требований. Данная книга предназначена для того, чтобы помочь вам определить, оправдано ли применение XP в вашей ситуации...
Кент Бек
Экстремальное программирование
Посвящается моему отцу, а также благодарю Синди (Cindee Andres), мою жену и партнера, за то, что она требовала, чтобы я не обращал на нее внимания и писал. Спасибо Бетани (Bethany), Линкольну(Lincoln), Форресту (Forrest) и за то, что они не отвлекали меня и предоставили мне писать.
Кент Бек, консультант серии
Предисловие
Экстремальное программирование (eXtreme Programming , XP) определяет кодирование как ключевую и основополагающую деятельность при работе над программным проектом. Возможно, что это неправильно!
Думаю, что стоит вспомнить о моем собственном опыте разработки программного обеспечения. Я работаю в среде, где разрабатываемый продукт постоянно находится в работоспособном состоянии, и при этом в него постоянно вносятся изменения. Сроки выпуска очередной работоспособной версии чудовищно сжаты, и при этом над всем этим нависает огромный технический риск. В подобной среде способность поправить своего соратника – это искусство, без которого не выжить. Обмен информацией как внутри некоторой команды, так и между несколькими командами, которые часто разделены географически, выполняется при помощи кода. Мы читаем код для того, чтобы понять устройство новых или модифицированных программных интерфейсов системы. Жизненный цикл и поведение сложных объектов определяются с использованием тестовых случаев, то есть снова при помощи кода. Сообщения о возникающих проблемах сопровождаются тестовыми случаями, демонстрирующими проблему, для этого опять используется код. Наконец, мы постоянно заняты улучшением существующего кода, делая его более производительным, более гибким, более понятным. Очевидно, что в подобных условиях разработка программного продукта почти целиком основана на кодировании, однако при этом нам удается с успехом завершать проекты к сроку, таким образом, данный подход вполне жизнеспособен.
Не следует делать вывод, что все, что вам потребуется для успешной реализации программного проекта, – это безоглядное ожесточенное программирование. Разрабатывать программное обеспечение очень непросто, а разрабатывать качественное программное обеспечение и при этом завершать работу в срок – еще сложнее. Чтобы описанный мною подход сработал, необходимо последовательное применение важных дополнительных правил и методик. Именно с этого Кент Бек (Kent Beck) начинает свою побуждающую к размышлениям книгу об ХР.
Кент был среди тех руководителей компании Tektronix, которые осознали огромный потенциал, заложенный в методике программирования в связанных парах при разработке сложных инженерных приложений в среде Smalltalk. Вместе с Бардом Каннингхемом (Ward Cunningham) Кент стал вдохновителем развития методики программирования по образцам (ее еще называют программированием с использованием паттернов – patterns programming[1] , которая в значительной степени повлияла на мою собственную карьеру. В рамках ХР описывается подход к разработке программного обеспечения, который сочетает в себе методики, используемые многочисленными успешно работающими разработчиками, которые изучили множество литературы, посвященной организации труда программистов, и опробовали на практике множество методов и процедур разработки программного продукта. Как и программирование по образцам, ХР формирует набор наиболее эффективных методик, таких как тестирование программных модулей, программирование парами и переработка кода. В рамках ХР эти методики скомбинированы таким образом, чтобы дополнять и часто контролировать друг друга. Основная цель данной книги – рассказать о взаимодействии и совместном использовании различных методик. У всех методик программирования одна цель – создание программного продукта с заданной функциональностью к заданному сроку. Предлагаемый OTI весьма успешный процесс Just In Time Software не является ХР в чистом виде, однако между этими двумя подходами очень много общего.
Я сотрудничал с Кентом и использовал описанные в рамках ХР эпизоды при работе над небольшим, но небезызвестным проектом под названием JUnit[2]. Его взгляды и подходы к разработке программ всегда за ставляли меня задумываться над тем, как лично я привык работать над программным проектом. Без сомнения, ХР ставит под вопрос многие традиционные подходы, используемые в индустрии программирования. Прочитав данную книгу, вы сможете самостоятельно решить, надо ли вам применять ХР в своей работе или нет.
Эрих Гамма (Erich Gamma)
Введение
Эта книга об экстремальном программировании (eXtreme Programming , XP). Экстремальное программирование – это упрощенная методика организации производства для небольших и средних по размеру команд специалистов, занимающихся разработкой программного продукта в условиях неясных или быстро меняющихся требований. Данная книга предназначена для того, чтобы помочь определить, оправдано ли применение ХР в вашей ситуации.
Для многих ХР выглядит набором вполне приемлемых и оправданных с точки зрения здравого смысла методов организации труда. Тогда почему программирование в соответствии с методиками ХР называется экстремальным? Дело в том, что ХР доводит использование многих общепринятых и широко используемых принципов программирования до экстремальных уровней.
• Если пересмотр кода – это хорошо, значит, мы будем пересматривать код постоянно (программирование парами);
• Eсли тестирование – это хорошо, каждый участник проекта будет тестировать код программы постоянно (тестирование модулей), даже заказчики (функциональное тестирование);
• Eсли проектирование – это хорошо, значит, проектирование надо сделать составной частью повседневной работы каждого из участников проекта (переработка кода);
• Eсли простота – это хорошо, значит, мы должны сохранять в системе наиболее простой дизайн, обеспечивающий текущий требуемый уровень функциональности (наиболее простая вещь, которая, скорее всего, сработает); если архитектура важна, значит, каждый из участников проекта будет постоянно работать над определением и пересмотром архитектуры (метафора);
• Eсли интеграционное тестирование важно, значит, необходимо собирать и тестировать разрабатываемую систему несколько раз на дню (продолжающаяся интеграция);
• Eсли небольшие итерации – это хорошо, необходимо сделать итерации очень, очень маленькими – секунды, минуты, может быть часы, но не недели и месяцы, и ни в коем случае не годы (игра в планирование).
Когда я впервые решил сформулировать для себя суть ХР, я представил себе набор рукояток на пульте управления. Каждая рукоятка соответствовала некоторой методике, о которой из своего личного опыта я знал, что она вполне эффективна. Каждая рукоятка позволяла использовать ту или иную методику в определенной степени: от 1 до 10. Я попробовал установить все рукоятки в максимально возможное положение (10) и с удивлением обнаружил, что полный набор рассматриваемых мной методик остается стабильным, предсказуемым и гибким.
ХР формирует два набора обещаний:
• Программистам ХР обещает, что каждый из них будет работать над решением действительно важных задач каждый рабочий день. Каждый из них никогда не окажется в затруднительном положении в одиночку. Каждый из них будет способен сделать все от него зависящее для того, чтобы сделать разрабатываемую систему удачной. Каждый из них будет способен принять решение именно в той области, в которой он компетентен, и если в некоторой области он не достаточно компетентен, он не будет участвовать в принятии решения.
• Заказчикам и менеджерам ХР обещает, что они получат максимальную возможную отдачу от каждой недели работы над проектом. Каждые несколько недель они будут способны увидеть прогресс в достижении заданных ими целей. Они получат возможность изменить направление развития проекта в самой середине разработки, не опасаясь при этом дополнительных экстраординарных затрат.
Если говорить коротко, ХР обещает снизить связанный с проектом риск, улучшить реакцию на изменение бизнеса, улучшить производительность работы над проектом и сделать процесс разработки программного обеспечения более приятным – и все это в одно и то же время. Я не шучу, хватит смеяться. Просто прочитайте эту книгу, и вы сами сможете проверить, сошел ли я с ума.
От издательства
Ваши замечания, предложения, вопросы отправляйте по адресу электронной почты comp@piter.com (издательство Питер, компьютерная редакция).
Мы будем рады узнать ваше мнение!
Все исходные тексты, приведенные в книге, вы можете найти по адресу http://www.piter.com/download.
На web‑сайте издательства http://www.piter.com вы найдете подробную информацию о наших книгах.
Часть 1.
Глава 1.
Риск: основная проблема
Существующие дисциплины разработки программного обеспечения не срабатывают и не дают желаемого экономического эффекта. Эта проблема обладает огромным экономическим и гуманитарным значением. Мы нуждаемся в новом способе разработки программного обеспечения.
Основная проблема разработки программного обеспечения – это риск .
Вот несколько примеров риска.
• Смещение графиков – наступает день сдачи работы, и вы вынуждены сообщить заказчику, что разрабатываемая система не будет готова еще в течение шести месяцев.
• Закрытие проекта – после нескольких смещений графика и переносов даты сдачи проект закрывается, даже не будучи доведен до стадии опробования в рабочих условиях.
• Система теряет полезность – разработанное программное обеспечение успешно устанавливается в реальной производственной рабочей среде, однако после пары лет использования стоимость внесения в нее изменений и/или количество дефектов увеличиваются настолько, что становится дешевле заменить систему новой разработкой.
• Количество дефектов и недочетов – программная система устанавливается в реальной производственной рабочей среде, однако количество дефектов и недочетов столь велико, что система не используется.
• Несоответствие решаемой проблеме – программная система устанавливается в реальной производственной рабочей среде, однако выясняется, что на самом деле она не решает проблему бизнеса, для решения которой она изначально предназначалась.
• Изменение характера бизнеса – программная система устанавливается в реальной производственной рабочей среде, однако в течение шести последних месяцев проблема, для решения которой предназначалась эта система, потеряла актуальность, а вместо нее бизнес столкнулся с новой, еще более серьезной проблемой.
• Недостаток возможностей – программная система обладает множеством потенциально интересных возможностей, каждую из которых было очень приятно программировать, однако выясняется, что ни одна из этих возможностей не приносит заказчику достаточно много пользы.
• Текучка кадров – в течение двух лет работы все хорошие программисты, работавшие над проектом, один за другим возненавидели разрабатываемую программную систему и ушли на другую работу.
На страницах данной книги вы прочитаете об экстремальном программировании (eXtreme Programming , XP) – дисциплине разработки программного обеспечения, которая ориентирована на снижение степени риска на всех уровнях процесса разработки. ХР способствует существенному увеличению производительности и улучшению качества разрабатываемых программ, кроме того, это весьма занятная практика, доставляющая всем ее участникам массу удовольствия.
Каким образом ХР снижает перечисленные ранее риски?
• Смещение графика – ХР предлагает использовать очень короткие сроки выпуска каждой очередной версии. Предполагается, что каждая очередная готовая к использованию версия системы разрабатывается в течение максимум нескольких месяцев. Таким образом, объем работ в рамках каждой версии ограничен, а значит, если и происходит смещение, оно менее значительное. В рамках каждой версии предусматривается выпуск нескольких итераций запрашиваемых заказчиком возможностей, на разработку каждой из этих итераций уходит от одной до четырех недель. Так обеспечивается гибкая и чуткая обратная связь с заказчиком, благодаря чему он получает представление о текущем ходе работ. В рамках каждой итерации планирование в соответствии с ХР осуществляется в терминах нескольких задач, которые необходимо решить для получения очередной итерации. На решение каждой из задач отводится от одного до трех дней. В результате команда может обнаруживать и устранять проблемы даже в процессе итерации. Наконец, ХР подразумевает, что возможности с наивысшим приоритетом будут реализованы в первую очередь. Таким образом, любые возможности, которые не удалось реализовать в рамках данной очередной версии программного продукта, обладают меньшим приоритетом.
• Закрытие проекта – в рамках ХР заказчик должен определить наименьший допустимый набор возможностей, которыми должна обладать минимальная работоспособная версия программы, имеющая смысл с точки зрения решения бизнес‑задач. Таким образом, программистам потребуется приложить минимальное количество усилий для того, чтобы заказчик понял, нужен ли ему этот проект или нет.
• Система теряет полезность – в рамках ХР создается и поддерживается огромное количество тестов, которые запускаются и перезапускаются после внесения в систему любого изменения (несколько раз на дню), благодаря этому удается тщательно следить за качеством разрабатываемой программы. ХР постоянно поддерживает систему в превосходном состоянии. Дефектам просто не дают накапливаться.
• Количество дефектов и недочетов – в рамках ХР разрабатываемая система тестируется как программистами, создающими тесты для каждой отдельной разрабатываемой функции, так и заказчиками, которые создают тесты для каждой отдельной реализованной возможности системы.
• Несоответствие решаемой проблеме – в рамках ХР заказчик является составной частью команды, которая работает над проектом. Спецификация проекта постоянно перерабатывается в течение всего времени работы над проектом, благодаря этому любые уточнения и открытия, о которых заказчик сообщает команде разработчиков, немедленно находят свое отражение в разрабатываемой программе.
• Изменение характера бизнеса – в рамках ХР цикл работы над очередной версией программы существенно укорачивается. Таким образом, ко времени выхода очередной работоспособной версии программного продукта бизнес не успевает претерпеть существенных изменений. В процессе работы над очередной версией заказчик может попросить отказаться от разработки некоторой функциональности и вместо нее добавить в программный продукт другие, совершенно новые возможности. Команда разработчиков даже не обратит внимания на то, работает ли она над реализацией новых программных механизмов, или осуществляется разработка возможностей, определенных еще несколько лет назад.
• Недостаток возможностей – в рамках ХР осуществляется реализация только наиболее высокоприоритетных задач.
• Текучка кадров – ХР предлагает программистам брать на себя ответственность самостоятельно определять объем работы и время, необходимое для выполнения этой работы. Они получают возможность сравнить свои предварительные оценки с тем, что получилось на самом деле. В рамках ХР содержатся правила, определяющие, кто именно имеет право делать предварительные оценки и изменять их.
За счет этого существенно снижается вероятность того, что программист окажется в растерянности перед возложенной на него задачей, которую заведомо невозможно решить. ХР стимулирует интенсивное общение между членами команды разработчиков, снижая ощущение одиночества, которое может возникнуть в случае, если программист не доволен работой, которую он делает. Наконец, в рамках ХР явно определяется модель смены кадров. Новые члены команды постепенно берут на себя все большую и большую ответственность.
В процессе этого они пользуются поддержкой друг друга, а также программистов, которые входят в состав команды уже давно.
Глава 2.
Эпизод из программистской практики
День за днем программист выполняет одну и ту же последовательность действий, которую можно назвать программным проектом в миниатюре: он изучает задачу, четко связанную с возможностью продукта, в которой нуждается заказчик, затем он формирует набор необходимых тестов, реализует поставленную задачу, вылизывает код, а потом интегрирует его в систему. В каждом таком эпизоде содержатся все этапы, которые обычно составляют процесс разработки крупного программного продукта.
Для начала небольшой экскурс вперед, то есть туда, куда мы с вами движемся. Данная глава описывает живой процесс экстремального программирования так, как это происходит на практике. Речь пойдет об эпизоде разработки. Эпизод разработки – это фрагмент деятельности программиста, когда он реализует некоторую инженерную задачу (наименьший квант планирования) и интегрирует ее с остальной системой.
Я смотрю на мой набор карточек с задачами. На самой верхней из них написано: Экспорт значения квартальных издержек на момент обращения к системе. Я вспоминаю, что на сегодняшнем утреннем совещании ты сообщил присутствующим, что завершил блок вычисления значения квартальных издержек. Я обращаюсь к тебе (моему гипотетическому соратнику) с вопросом, не найдется ли у тебя времени помочь мне с разработкой блока экспорта. Ты отвечаешь: Конечно! Это одно из основных правил ХР: если к тебе обращаются с просьбой о помощи, ты обязан ответить да. Таким образом мы становимся партнерами по программированию в паре.
В течение пары минут мы обсуждаем работу, которую ты выполнил вчера. Ты рассказываешь мне о добавленном тобою в систему коде, о бинарных значениях и о том, как выглядят соответствующие тесты. Мы отодвигаем мой монитор чуть назад, так как при этом эффективность парного программирования несколько увеличивается.
Ты спрашиваешь у меня: Как выглядят тестовые случаи для этой задачи?
Я отвечаю: После выполнения экспортирующего кода значения в экспортированной записи должны соответствовать бинарным значениям.
Ты спрашиваешь: Какие поля требуется заполнить?
Я не знаю, надо спросить у Эдди.
Мы отрываем Эдди от работы на тридцать секунд, и он рассказывает нам о пяти полях, которые связаны с квартальными издержками.
Мы обращаемся к изучению структуры некоторых существующих тестовых случаев, связанных с экспортом. Обнаруживается, что один из тестовых случаев почти полностью нам подходит. Если, используя обнаруженный нами код, создать абстрактный суперкласс, на его основе мы могли бы с легкостью реализовать наш тестовый случай. Так мы выполняем переработку кода (refactoring). Потом мы запускаем существующие тесты, и все они успешно выполняются.
После этого мы обращаем внимание, что несколько других тестовых случаев можно переработать так, чтобы они были основаны на только что созданном нами абстрактном суперклассе. Однако нам необходимо решить стоящую перед нами конкретную задачу, поэтому мы просто берем пустую карточку, записываем на ней выполнить переработку тестовых случаев с использованием класса AbstractExportTest и размещаем эту карточку в наборе задач, которые нам предстоит выполнить.
После этого мы разрабатываем наш тестовый случай. Благодаря тому, что перед этим мы разработали суперкласс, создание нового тестового случая не представляет труда. Мы выполняем эту работу в течение нескольких минут. Где‑то в середине работы я говорю: Я уже представляю себе, как мы можем это реализовать. Мы можем...
Однако ты прерываешь меня: Давай сначала завершим работу над тестовым случаем. Пока мы пишем тестовый случай, в голову приходят идеи для трех вариаций. Ты записываешь их на очередной карточке.
Мы завершаем работу над тестовым случаем и запускаем его. Он не срабатывает. Естественно, мы ведь еще ничего не реализовали. Подожди минутку, – говоришь ты, – вчера, когда мы с Ральфом работали над блоком вычислений, мы написали пять тестовых случаев, о которых мы думали, что они не сработали. Все, за исключением одного, сработали с первого раза.
Мы запускаем отладчик и приступаем к изучению работы тестового случая. Мы анализируем объекты, с которыми имеет дело наш тестовый случай.
Я пишу код (или это делаешь ты – все зависит от того, у кого из нас возникнет более удачная идея). Пока мы работаем над реализацией, мы замечаем еще пару дополнительных тестовых случаев, которые неплохо было бы написать. Мы заносим эту информацию на карточку. После того как код реализован, ранее разработанный тестовый случай срабатывает.
Мы переходим ко второму тестовому случаю, затем к третьему. Я реализую их. Ты обращаешь внимание, что код можно упростить. Мне с трудом удается одновременно слушать твои объяснения и продолжать писать код, поэтому я просто передаю тебе клавиатуру. Ты перерабатываешь код, после этого ты запускаешь тестовые случаи и они срабатывают. Ты приступаешь к реализации следующей пары тестовых случаев.
Спустя некоторое время мы смотрим на набор карточек с заданиями, которые необходимо доделать, и обнаруживаем, что нам осталось переделать тестовые случаи, которые были разработаны ранее. Все идет хорошо, и мы переделываем их, а затем убеждаемся в том, что все они срабатывают.
Теперь список дел, которые нам необходимо выполнить, пуст. Мы обращаем внимание на то, что компьютер, на котором выполняется интеграция, свободен. Мы загружаем последнюю версию системы, затем мы загружаем наши последние изменения. Затем мы запускаем все тестовые случаи, потом запускаем новые тестовые случаи, только что разработанные нами, а затем абсолютно все тестовые случаи, которые кто‑либо когда‑либо разрабатывал. Один из них не срабатывает. Это очень странно, – произносишь ты, – прошло не меньше месяца с тех пор, когда я в последний раз сталкивался со сбоем тестового случая в процессе интеграции. Однако особых проблем в этом нет. Мы отлаживаем тестовый случай и исправляем код. После этого мы вновь запускаем весь полный набор тестов. На этот раз все они срабатывают. Мы включаем наш код в состав системы.
Вот так выглядит полный цикл разработки кода в рамках ХР. Следует обратить внимание на следующие обстоятельства.
• Два программиста работают над решением задачи вместе в одной паре.
• Разработка базируется на тестах. Сначала вы пишете тесты, затем – код. Вы не можете считать работу доделанной до тех пор, пока все тесты не сработают. Если все тесты сработали и вы не в состоянии придумать еще каких‑либо других тестов, которые могут не сработать, вы можете считать, что добавление функциональности завершено.
• Пары программистов не только добиваются того, чтобы тестовые случаи срабатывали. Они также выполняют эволюцию дизайна системы. Изменения не ограничиваются какой‑то отдельной конкретно очерченной областью. Пары программистов вносят свой вклад в анализ, дизайн, реализацию и тестирование всей системы. Добавление изменений осуществляется тогда, когда система нуждается в этих изменениях.
Сразу же за разработкой следует интеграция, которая включает в себя также интеграционное тестирование.
Глава 3.
Варианты
Есть еще один взгляд на экономику программного проекта – это набор вариантов, в соответствии с которыми может развиваться этот проект. Управление программным проектом может осуществляться в соответствии с одним из вариантов.
• Вариант закрыть проект – вы можете получить какую‑либо прибыль даже в случае, если работа над проектом будет прервана. Чем большую выгоду вы получите от проекта, который был завершен, не достигнув изначально планировавшегося состояния, тем лучше.
• Вариант смены направления – вы можете изменить направление развития проекта. Стратегия управления проектом будет более выгодной в случае, если в процессе работы над проектом заказчики будут обладать возможностью сменить изначально сформулированные ими требования. Чем чаще это может происходить и чем кардинальнее заказчики могут менять свои требования, тем лучше.
• Вариант отсрочки решения – прежде чем инвестировать средства и ресурсы в том или ином направлении, вы можете подождать до тех пор, пока ситуация сама собой не разрешится и не станет более понятной для вас. Стратегия управления проектом будет более выгодной в случае, если вы будете обладать возможностью подождать с вложением денег, и при этом не потерять полностью возможность инвестирования средств. Чем более длительной может быть отсрочка и чем большее количество денег можно удержать от преждевременного инвестирования, тем лучше.
• Вариант роста инвестиций – если вы видите, что рынок начинает расти, вы можете оперативно увеличить инвестиции для того, чтобы с выгодой воспользоваться этим. Стратегия управления проектом будет более выгодной в случае, если вы будете обладать возможностью все больше и больше расширять производство за счет увеличения объема инвестиций. Чем быстрее и чем дольше проект может расти, тем лучше.
Определение значимости каждого из вариантов – это на две части искусство, на пять частей – математика и на одну часть – старое доброе перетягивание каната.
При этом необходимо учитывать следующие пять факторов:
• объем инвестиций, необходимых для реализации того или иного варианта;
• цена, в рамках которой вы сможете достигнуть цели, если вы будете действовать в рамках того или иного варианта;
• текущая ценность поставленной вами цели;
• время, которое потребуется вам для того, чтобы реализовать тот или иной вариант;
• неопределенность, с которой вы можете оценить ценность поставленной вами цели.
Из всех этих факторов доминирующим как правило оказывается последний: неопределенность. На основании этого мы можем прийти к некоторым выводам и прогнозам относительно разрабатываемой нами стратегии. Представьте, что мы создали стратегию управления проектом, которая максимизирует полезность проекта на основе анализа вариантов и обеспечивает:
• частый возврат точных сведений о текущем состоянии разработки;
• множество возможностей в значительной степени изменить набор изначально заданных требований и направление развития проекта;
• меньший объем изначальных инвестиций;
• возможность при желании увеличить темпы разработки.
Чем большей будет неопределенность, тем полезнее окажется созданная нами стратегия. Это утверждение является справедливым вне зависимости от того, является ли причиной неопределенности технический риск, изменяющиеся условия, в которых функционирует бизнес, или быстро эволюционирующие требования заказчика. (Это является теоретическим ответом на вопрос: Надо ли мне использовать ХР? Использовать ХР следует в условиях, когда требования заказчика неопределенны или быстро меняются.)
Пример
Представьте, что вы занимаетесь программированием фактически в одиночку. Вы видите, что добавление в программу некоторой возможности обойдется вам в $10. Вы ожидаете, что вы сможете заработать на этой возможности приблизительно $15. Таким образом, чистая текущая ценность (Net Present Value, NPV) добавления в программу данной возможности составит $5.
Представьте, что вы не можете сказать точно, какова будет на самом деле ценность рассматриваемой вами возможности, – вы можете лишь предположить, что заказчик будет готов заплатить за нее $15. В действительности этот параметр может отличаться от предполагаемого вами значения на 100% в обе стороны. Теперь предположим, что если вы соберетесь добавлять данную возможность спустя год от текущего момента, то это все равно будет стоить вам те же $10 (см. главу 5).
Какова будет ценность стратегии, в рамках которой вы не будете реализовывать эту возможность прямо сейчас, а подождете в течение года? В настоящее время средняя процентная ставка составляет около 5% годовых. С учетом этой процентной ставки искомая ценность составит около $7,87.
Следовательно, стратегия годичного ожидания, прежде чем добавить в программу новую возможность, обойдется нам дороже, чем если бы мы, ничего не ожидая, прямо сейчас инвестировали деньги в разработку данной возможности (напомню, что на текущий момент соответствующая NVP составляет $5). Почему? В настоящее время мы находимся в неопределенности и не можем точно сказать, будет ли данная возможность действительно полезна для нашего заказчика и сможет ли он прямо сейчас начать зарабатывать на ней деньги. Если мы реализуем возможность прямо сейчас и возможность окажется действительно полезной, то наш заказчик через год получит за счет этого определенную прибыль. Однако может оказаться, что для нашего заказчика эта возможность не представляет никакой ценности, и поэтому, отказавшись на текущий момент от ее реализации, мы можем сэкономить собственные ресурсы.
Говоря проще, варианты помогают нам избавиться от нежелательного риска.
Глава 4.
Четыре переменные
В наших проектах мы пытаемся контролировать четыре переменные – затраты, время, качество и объем работ. Из всех этих переменных наиболее удобной для контроля является объем работ.
В данной главе я расскажу вам о модели разработки программного обеспечения, которая представляет собой систему контролируемых переменных. В рамках дайной модели разработка программного обеспечения определяется с использованием следующих четырех переменных:
• затраты (cost);
• время (time);
• качество (quality);
• объем работ (scope).
В данном случае игра в разработку программного обеспечения выглядит следующим образом: внешние силы (заказчики, менеджеры) должны определить значения для любых трех переменных из указанного набора, при этом команда разработчиков должна выбрать результирующее значение для оставшейся переменной.
Некоторые менеджеры и заказчики полагают, что они обладают правом с успехом установить значение для всех четырех переменных. Вы обязаны реализовать все, что указано в техническом задании к первому числу следующего месяца, работая в текущем составе, то есть без увеличения численности, при этом качество должно стоять на первом месте и не уступать нашим обычным стандартам. Когда происходит подобное, качество, как правило, летит ко всем чертям (и это, к сожалению, как раз и является общераспространенным стандартом), потому что никто не в состоянии хорошо делать свою работу под слишком большим давлением. Помимо качества, время, как правило, также выходит из‑под контроля. Таким образом, вы производите некачественное программное обеспечение, не успевая при этом сдать работу к сроку.
Чтобы решить проблему, необходимо сделать все четыре переменные наблюдаемыми. Если все – программисты, заказчики и менеджеры – смогут наблюдать за поведением всех четырех переменных, будет легче сознательно выбрать, какие из четырех переменных следует контролировать. Если результирующее значение четвертой переменной окажется неприемлемым, можно будет либо изменить входные значения, либо выбрать для контроля другие три переменные.
Глава 5
Стоимость внесения изменений
При определенных условиях экспоненциально растущую относительно времени стоимость внесения изменений в систему можно сгладить. Если кривая роста стоимости внесения изменений в систему сглаживается, старые правила, определяющие наилучшие методики разработки программного обеспечения, перестают быть верными.
Одно из общепринятых фундаментальных правил, определяющих традиционную стратегию разработки программного обеспечения, утверждает, что по мере работы над проектом стоимость внесения изменений в разрабатываемый программный продукт увеличивается экспоненциально. Я помню, как, будучи студентом колледжа, сидел в огромной аудитории, пол которой был покрыт блестящим линолеумом, и смотрел, как профессор рисует на доске кривую, изображенную на рис. 1.
Рис. 1. С течением времени стоимость внесения изменений в программный продукт возрастает экспоненциально
Затраты, связанные с исправлением проблемы, обнаруженной внутри программного продукта, растут экспоненциально с течением времени, – говорил профессор. – Проблема, для решения которой в процессе анализа требований потребовался бы доллар, может стоить вам нескольких тысяч долларов, если вы обнаружите ее в момент, когда система уже будет в производстве.
Тогда, в той аудитории я раз и навсегда решил для себя, что я никогда не позволю проблемам оставаться в разрабатываемых мною программах до самого производства. Ни за что! Я обязательно буду устранять проблемы так быстро, как только это возможно. Я буду бороться с проблемами, которые даже еще не возникли, а только могут возникнуть. Я буду постоянно и беспрерывно пересматривать и проверять мой код. Ни под каким видом я не позволю себе допустить ошибку, которая в будущем будет стоить моему нанимателю сотни тысяч долларов.
Однако проблема состоит в том, что на самом деле кривая, изображенная на рис. 1, больше не соответствует действительности. Говоря точнее, благодаря использованию новых технологий и специальных методик программирования можно добиться того, что кривая стоимости внесения изменений в программный продукт будет выглядеть прямо противоположно. Теперь становятся возможными истории, подобные следующей, которая случилась со мной относительно недавно, во время работы над системой управления контрактами страхования жизни:
17.00 – я обнаруживаю, что некоторая встроенная в нашу систему возможность – способность в рамках одной трансакции хранить несколько дебетов с нескольких учетных записей и несколько кредитов для нескольких учетных записей – в процессе функционирования системы, по сути дела, не используется. Каждая трансакция извлекает средства только с одной учетной записи и переносит их только на одну учетную запись. У меня в голове возникает вопрос: можно ли упростить систему, как показано на рис. 2?
Рис. 2. Можем ли мы использовать только один компонент для каждой пары дебет/кредит?
17.02 – я обращаюсь к Массимо и прошу его, чтобы он подошел ко мне и сел рядом для того, чтобы помочь мне разобраться в ситуации. Мы пишем запрос. Выясняется, что из всех 300 000 трансакций в системе ни одна не использует более одной учетной записи для снятия денег и более одной учетной записи для переноса денег. Каждой из трансакций соответствует только одна дебетная учетная запись и только одна кредитная учетная запись.
17.05 – если мы хотим исправить систему, как мы можем этого достичь? Мы можем изменить интерфейс компонента Transaction, а также изменить реализацию. Мы переписываем четыре требуемых метода и приступаем к тестированию.
17.15 – все тесты (более чем 1000 модульных и функциональных тестов) по‑прежнему выполняются на 100% отлично. Мы не можем придумать ситуацию, в которой внесенные нами изменения могут стать причиной неработоспособности системы. Мы приступаем к работе над кодом миграции базы данных.
17.20 – мы завершаем программирование процедур миграции, которая должна быть выполнена в течение ночи. Также мы выполняем резервное копирование базы данных. После этого мы устанавливаем новую версию кода и инициируем процесс миграции.
17.30 – мы запускам несколько проверочных тестов. Все, что мы могли предусмотреть, работает великолепно. Не в состоянии придумать чтолибо важное, о чем мы могли позабыть, мы уходим домой.
Следующий день – журнал ошибок пуст. Никаких жалоб от пользователей не поступает. По всей видимости, внесенные нами изменения отлично работают.
В течение нескольких следующих недель мы обнаружили, что в связи с использованием новой структуры разрабатываемую нами систему можно упростить еще больше. При этом мы получаем возможность внести в бухгалтерский раздел нашей программы совершенно новую удобную функциональность. Таким образом мы делаем систему проще, чище и менее избыточной.
В течение последних нескольких десятилетий сообщество людей, работающих в области разработки программного обеспечения, приложило огромные усилия для того, чтобы снизить стоимость внесения изменений. Для этой цели были разработаны более совершенные языки программирования, более совершенные технологии баз данных, более эффективные методики кодирования, улучшенные среды и инструменты разработки, новые правила.
Что, если все эти инвестиции не пропали даром? Что, если вся эта суета с новыми языками программирования и новыми базами данных не была напрасной? Что, если теперь стоимость внесения изменений не растет экспоненциально, как раньше, а увеличивается более медленно, со временем приближаясь к асимптоте? Что, если завтра профессор, преподающий студентам основы разработки программного обеспечения, нарисует на доске линию, изображенную на рис. 3?
Рис. 3. Стоимость изменений со временем может увеличиваться существенно медленнее, чем экспонента
Именно это является одним из основных предположений ХР. Это техническое предположение ХР. Если стоимость внесения в систему изменений со временем растет достаточно медленно, стратегия разработки программы должна быть совершенно другой, отличной от той, которая используется в случае, если стоимость внесения в систему изменений современем растет экспоненциально. В подобной ситуации вы можете откладывать решение важных задач на более поздние сроки. Вы получаете возможность принимать важные решения настолько поздно, насколько это возможно. Это делается для того, чтобы осуществлять связанные с этим затраты как можно позже. Кроме того, если вы откладываете решение важных вопросов на более поздний срок, тем самым вы повышаете вероятность того, что выбранное вами решение окажется правильным. Другими словами, сегодня вы должны реализовать только то, без чего сегодня не обойтись, при этом вы можете рассчитывать на то, что проблемы, решение которых вы отложили до завтра, развеются сами собой, то есть перестанут быть актуальными. Вы можете добавлять в дизайн новые элементы только в случае, если эти новые элементы упрощают код или делают написание следующего фрагмента кода более простым.
Если пологая кривая роста затрат делает ХР возможным, то экспоненциальная кривая роста затрат делает ХР невозможным. Если изменение обойдется вам в кругленькую сумму, вы сойдете с ума, пытаясь предугадать, каким образом это изменение повлияет на работу системы. Если же изменение обходится вам дешево, вы всегда можете рискнуть и проверить, что будет, если вы тем или иным образом измените код, – позже вы всегда можете изменить систему так, как это будет лучше. В подобной ситуации, внеся изменения в систему, вы через короткое время получаете ответную информацию о том, насколько полезны данные изменения для системы.
Но как поддерживать невысокую стоимость изменений на протяжении всего времени работы над проектом? Сохранение низкой стоимости изменений – это не какой‑то магический трюк, оно достигается не просто так, а в результате применения технологий и методик, которые позволяют сделать программный продукт податливым и легко модернизируемым.
С технологической точки зрения ключевой технологией, позволяющей добиться этого, являются объекты. Обмен сообщениями между объектами позволяет существенно расширить спектр возможностей по изменению разрабатываемой системы. Каждое сообщение становится потенциальной точкой для внесения в систему грядущих модификаций, модификаций, которые могут вносится в систему, не затрагивая при этом существующий код.
Объектные базы данных переносят эту гибкость в пространство постоянной памяти. Благодаря использованию объектной базы данных вы получаете возможность с легкостью переносить информацию об объектах из одного формата в другой, так как в объектных базах данных код соединен с данными, а не отделен от них, как это было в более ранних базах данных. Даже если вы не можете найти способ выполнить миграцию объектов, вы можете обеспечить в рамках одной системы сосуществование двух разных реализаций.
Я вовсе не хочу сказать, что вы обязаны использовать объекты для того, чтобы получить гибкость. Лично я познакомился с основами ХР, когда наблюдал, как мой отец пишет на ассемблере управляющий код процесса реального времени. Он разработал стиль, который позволил ему постоянно обновлять дизайн его программ. Все же мой опыт подсказывает мне, что стоимость изменений увеличивается в большей степени в случае, если вы не используете объекты, чем в случае, если вы основываете свой проект на объектно‑ориентированном подходе.
Я также не хочу сказать, что объекты – это все, что вам потребуется для снижения стоимости затрат. Я видел (и даже, по правде сказать, сам написал) немало кодов, заниматься изменением которых я не пожелал бы и врагу.
Чтобы упростить модификацию вашего кода даже спустя несколько лет после начала работы над проектом, вы должны учитывать следующие факторы:
• простой дизайн, в котором отсутствуют лишние элементы, – никаких идей, которые на текущий момент не используются, однако предположительно могут использоваться в будущем;
• автоматические тесты – благодаря им всегда с легкостью можно узнать о том, что в результате внесения в систему изменений ее поведение изменилось;
• постоянная практика в деле модификации дизайна системы – когда приходит время менять систему, вы не почувствуете страха перед этим.
Если мы заложим в основу нашей работы три перечисленных элемента – простой дизайн, автоматические тесты и опыт постоянного видоизменения системы, мы увидим, что кривая расходов, связанных с внесением в систему изменений, станет пологой, как на рис. 3. Изменение, для осуществления которого до начала кодирования потребовалось бы несколько минут, через два года работы над системой потребует от вас не более 30 минут. Однако я сталкивался с проектами, в которых на принятие и предварительное обдумывание подобных решений тратятся дни и даже недели, хотя вместо этого проблему можно решить уже сейчас, а завтра, если это потребуется, можно будет с легкостью все переделать на новый лад.
Теперь, когда мы кардинально пересмотрели наши изначальные предположения относительно стоимости внесения в систему изменений, у нас появляется возможность применить совершенно иной подход к разработке программного обеспечения. Как и любые другие подходы, разрабатываемый нами подход строг, он не терпит нарушения определяемых в его рамках правил, однако его строгость лежит в несколько иных измерениях. Вместо того чтобы заботиться о принятии важных решений как можно раньше и менее значительных решений – позже, мы с вами планируем разработать подход, в рамках которого каждое решение принимается быстро, при этом оно надежно защищается с использованием автоматических тестов. Помимо этого, в рамках нового подхода вы должны быть готовыми к изменению дизайна системы в случае, если вы понимаете, что существует более удачный дизайн, чем тот, который реализован вами на текущий момент.
Создание такого подхода – далеко не простая задача. Мы должны будем заново проанализировать и пересмотреть принятые нами ранее предположения о том, какая методика разработки программного обеспечения является хорошей, а какая – нет. Мы будем двигаться в сторону цели поэтапно. А начнем мы с рассказа, который будет притягивать к себе все остальное, чем мы будем заниматься.
Глава 6.
Обучение управлению автомобилем
Управляя разработкой программного продукта, мы должны совершать множество незначительных преобразований и воздействий. Мы должны избегать применения нескольких существенных модернизаций. Другими словами, управление разработкой программной системы в некотором смысле должно напоминать управление едущим автомобилем. Это означает, что у нас должна быть обратная связь для того, чтобы вовремя узнать о том, что мы несколько отклонились от желаемого направления движения. Мы должны обладать самыми широкими возможностями по внесению в проект изменений, кроме того, мы должны обладать возможностью вносить эти изменения ценой приемлемых для нас затрат.
Теперь у нас есть общая формулировка проблемы – угрожающе огромная цена риска и возможность управлять этим риском при помощи вариантов, кроме того, мы обладаем ресурсом, который потребуется нам для формирования решения: свобода вносить изменения позже, не увеличивая при этом связанные с этим затраты. Теперь мы должны сконцентрировать усилия на поиске решения. Самая первая вещь, которая нам для этого потребуется, – это метафора – образно оформленный рассказ, к которому мы могли бы обращаться время от времени в случае стресса или для поддержки.
Я отлично помню тот день, когда впервые начал учиться водить машину. Я и моя мать сели в машину и выехали на автостраду Interstate 5 вблизи Чико (Chico) в штате Калифорния. Это прямой как стрела пустынный участок шоссе, выходящий из‑под колес машины и, подобно натянутой струне, устремляющийся вдаль – к линии горизонта. Моя мать позволила мне пересесть в водительское кресло, а сама села на место переднего пассажира. И мы поехали. В начале я с осторожностью изучил, как именно движение рулевого колеса влияет на направление движения автомобиля, затем, освоившись, я позволил себе несколько расслабиться. Управлять машиной надо так, – учила меня моя мама, – направь машину строго по середине дороги и езжай по этой дороге прямо в направлении горизонта.
Мы ехали достаточно долго, и где‑то посередине нашего путешествия что‑то отвлекло мое внимание. Машина стала смещаться в сторону края дороги. Моя мать несколько обеспокоилась...
Когда колеса зашуршали по гравию на обочине, я немедленно опомнился. Моя мама (сейчас ее тогдашнее хладнокровие кажется мне ошеломляющим) плавно поправила руль так, чтобы машина вернулась на центр дороги. После этого она дала мне наиболее важное наставление относительно того, как следует управлять автомобилем:
Чтобы управлять автомобилем, вовсе не обязательно добиваться от него, чтобы он постоянно ехал в жестко заданном направлении. Достаточно внимательно следить за тем, куда едет машина, и поправлять направление ее движения – чуть‑чуть влево, затем чуть‑чуть вправо.
Это наставление является парадигмой для ХР. В рамках ХР не существует такой вещи, как прямое направление движения. Даже если вам кажется, что дела идут замечательно, вы не должны отрывать ваших глаз от дороги. Неизменными остаются только сами изменения. Всегда будьте готовы к тому, чтобы изменить направление чуть‑чуть в одну сторону, затем чуть‑чуть в другую сторону. В некоторых ситуациях вам придется менять направление так, что вы начнете движение в совершенно другую сторону. Такова жизнь программиста.
Абсолютно все в мире программного обеспечения меняется. Требования заказчиков меняются. Дизайн меняется. Бизнес видоизменяется. Технологии меняются. Команда разработчиков меняется. Члены команды разработчиков меняются. Сама по себе проблема остается неизменной, так как изменение рано или поздно должно произойти. На самом деле проблема состоит в том, что когда происходит изменение, люди не в состоянии с ним справиться.
Шофером программного проекта является заказчик. Если программа не делает того, чего заказчик от нее хочет, – это ваша неудача. Конечно же, заказчик не может сказать точно, чего именно он хочет от программы. Именно поэтому разработка программного продукта должна напоминать управление автомобилем. Редко когда кто‑либо едет на машине, стараясь, чтобы автомобиль ни на миллиметр не отклонился от желаемой жестко заданной прямой. Обычно люди стараются обеспечить движение в заданном направлении, слегка подправляя направление движения при помощи рулевого колеса. Как программисты мы должны предоставить заказчику рулевое колесо, а также обеспечить обратную связь, как можно чаще сообщая ему, в каком именно месте дороги находится наш автомобиль.
Рассказ об управлении автомобилем также определяет мораль процесса ХР. Описанные в следующей главе четыре ценности – коммуникация, простота, обратная связь и храбрость – дают представление о том, как должен выглядеть процесс разработки программного обеспечения. Однако методики, благодаря которым это достигается, будут отличаться для разных мест, разного времени и разных людей. Управляя процессом разработки, вы используете простой набор методик и стараетесь сформировать этот процесс так, как это описывается далее. По мере того как разработка продолжается, вы постоянно следите за тем, какие из методик требуют улучшения, а какие методики плохо соответствуют поставленной цели. Каждая методика – это эксперимент, который необходимо проводить до тех пор, пока не станет ясно, что он неадекватен.
Глава 7.
Четыре ценности
Мы сможем успешно решить стоящую перед нами проблему, если сформулируем стиль, который направлен на прославление каждой из согласующегося набора ценностей, которые служат как человеческим, так и коммерческим требованиям: коммуникация, простота, обратная связь и храбрость.
Прежде чем на основе рассказа об управлении автомобилем сформировать набор методик разработки программного обеспечения, мы должны найти некоторый критерий, благодаря которому сможем узнать о том, что движемся в правильном направлении. Согласитесь, что было бы плохо, если бы мы создали стиль разработки, а потом узнали, что этот стиль нам не нравится или что он не срабатывает.
Краткосрочные индивидуальные цели часто конфликтуют с долгосрочными социальными целями. Общество решает эту проблему при помощи набора ценностей, подкрепленных мифами, ритуалами, наказаниями и наградами. Без уважения к этим ценностям люди забывают о социальных нуждах и стремятся реализовать свой собственный индивидуальный краткосрочный интерес.
Четыре ценности для ХР – это:
• коммуникация (communication);
• простота (simplicity);
• обратная связь (feedback);
• храбрость (courage).
Глава 8.
Базовые принципы
Исходя из четырех ценностей мы сформулируем десяток (или около того) принципов, в соответствии с которыми будет формироваться наш стиль. В дальнейшем мы будем проверять рассматриваемые методики на соответствие этим принципам.
Рассказ об управлении автомобилем учит нас делать множество небольших изменений и при этом не отрывать глаз от дороги. Четыре ценности – коммуникация, простота, обратная связь и храбрость – предоставляют нам критерий для проверки качества решения. Все же четыре ценности слишком туманны для того, чтобы в значительной степени помочь нам в оценке, какие именно методики мы должны использовать. Мы должны извлечь из описанных ценностей конкретные принципы, которые мы сможем использовать, оценивая ту или иную методику.
Эти принципы помогут нам выбирать между несколькими альтернативами. Предпочтение будет отдаваться альтернативе, которая соответствует принципам в большей степени. Каждый из принципов является воплощением ценностей, о которых я рассказал в предыдущей главе. Ценность может быть туманной: например, то, что для одного человека является простым, для другого человека является сложным. Принцип – это нечто более конкретное. Либо вы используете быструю обратную связь, либо нет. Вот перечень фундаментальных принципов:
• быстрая обратная связь;
• приемлемая простота;
• постепенное изменение;
• приемлемое изменение;
• качественная работа.
Быстрая обратная связь – психология обучения учит нас тому, что время между воздействием и ответной реакцией имеет огромное значение при обучении. Эксперименты с животными показывают, что даже незначительная разница в задержках ответной реакции влечет за собой существенные отличия в обучении. Задержка в несколько секунд между стимулом и ответом приводит к тому, что мышь не может понять, что красная кнопка означает еду. Таким образом, одним из принципов должна стать наиболее высокая быстрота, с которой сведения о состоянии системы передаются тем, кто в них заинтересован. В рамках нашей дисциплины необходимо обеспечить быстрое получение этих сведений, быструю интерпретацию и быстрое внесение в систему модификаций, сформированных на основе анализа этих сведений. Все это необходимо выполнять с максимально возможной скоростью. Бизнес должен быстро определять, каким образом система будет полезной для него, и он должен возвращать разработчикам эти сведения в течение дней или недель, но не в течение месяцев или лет. Программисты должны изучать, каким образом лучше всего проектировать, реализовывать и тестировать систему, необходимые для этого сведения должны поступать к ним в течение секунд или минут, но не дней, недель и месяцев.
Приемлемая простота – необходимо решать каждую проблему так, как если бы ее можно было решить самым смехотворно простым способом. Времени, которое вы экономите на решении 98% проблем, для которых это утверждение является истинным, вполне хватает, чтобы справиться с решением оставшихся 2% проблем. Во многих смыслах этот принцип является наименее привычным и наиболее трудным для программистов. В рамках установившихся традиций мы приучены к тщательному планированию своих действий, мы привыкли проектировать код с расчетом на его дальнейшее повторное использование. Однако в рамках ХР огромные усилия (тестирование, переработка кода, коммуникация) прикладываются для того, чтобы сегодня программист думал о решении только сегодняшних проблем и был уверен в том, что завтра в случае необходимости имеющийся код можно будет с легкостью усовершенствовать так, как этого требует складывающаяся ситуация. Экономика разработки программ, представленная в виде набора нескольких вариантов, приветствует данный подход.
Постепенное изменение – объемные изменения, в рамках которых за один раз меняется абсолютно все, не срабатывают. Даже в Швейцарии, центре дотошного планирования, где я живу в настоящее время, люди избегают делать масштабные изменения. Любая проблема решается при помощи серии небольших изменений, в результате которых достигается желаемый эффект. Как будет показано, постепенное изменение применяется в ХР во многих областях и многими способами. Дизайн изменяется понемногу за один раз. План меняется понемногу за один раз. Команда меняется незначительно за один раз. Даже сама дисциплина ХР должна внедрятся постепенно – маленькими шажками.
Приемлемое изменение – лучшей стратегией является та, которая решает наиболее актуальную для вас проблему и при этом сохраняет для вас максимальную свободу дальнейших действий.
Качественная работа – никто не любит плохо работать. Каждому нравится делать свою работу на отлично. Из четырех ранее рассмотренных переменных (объем работ, затраты, время и качество) качество на самом деле не является свободно изменяемой переменной. Единственно возможными для нее значениями являются превосходно и невероятно превосходно – выбор между этими двумя значениями зависит от того, поставлены ли на карту человеческие жизни. В противном случае ваша работа вам не нравится, вы работаете плохо и ваш проект необратимо утекает в сточную канаву.
Далее приводится перечень менее важных принципов. Эти принципы все же могут помочь нам в определенных ситуациях:
• обучение обучению;
• небольшие изначальные инвестиции;
• игра для того, чтобы победить;
• надежное экспериментирование;
• открытая честная коммуникация;
• работа в соответствии с человеческими инстинктами, а не вопреки им;
• принимаемая ответственность;
• локальная адаптация;
• путешествие налегке;
• откровенные оценки.
Обучение обучению – вместо того чтобы сформировать набор доктрин наподобие вы должны тестировать так‑то и так‑то, мы должны сконцентрироваться на стратегиях обучения, благодаря которым мы смогли бы научиться заранее определять, какой объем тестирования нам потребуется. Точно так же мы не должны жестко определять объем проектирования, переработки и любых других действий. Мы должны научиться определять необходимый объем по ходу дела. Некоторые идеи мы можем принять со всей уверенностью. В отношении других идей мы будем менее уверенными. В отношении таких идей читатели должны самостоятельно определить, нуждаются ли они в них или нет.
Небольшие изначальные инвестиции – если на слишком ранней стадии вы вложите в проект слишком много денег, вы приведете этот проект к краху. Стесненный бюджет принуждает программистов и заказчиков избегать слишком завышенных требований и использовать более осторожные подходы. Обладая скромным бюджетом, вы стараетесь извлекать максимальную прибыль из того, чем вы обладаете, и с максимальной пользой использовать имеющиеся ресурсы. Однако чрезмерный недостаток ресурсов – это тоже плохо. Если у вас не хватает ресурсов на решение даже всего одной интересной для вас проблемы, разрабатываемая вами система перестанет быть для вас интересной. Если над вами нависает некто, кто диктует вам объем работ, сроки окончания, уровень качества и затраты, вы вряд ли сможете управлять проектом так, чтобы привести его к желаемому успешному финалу. А вообще, как показывает практика, в большинстве случаев каждый может обойтись меньшим запасом ресурсов, чем тот запас, с которым он чувствует себя комфортно.
Игра для того, чтобы победить – для меня всегда доставляет удовольствие смотреть, как играет баскетбольная команда UCLA Джона Вудена (John Wooden). Как правило, эти ребята выходят из поединка победителями. Однако даже тогда, когда игра близка к завершению, ребята из UCLA уверены, что они играют для того, чтобы победить. Конечно же, до этого они уже были победителями много‑много раз. Они несколько расслаблены. Однако при этом они делают все для того, чтобы выиграть. И они выигрывают вновь.
Я вспоминаю игру баскетбольной команды из Орегона, которая была ярким контрастом. Орегон сражался с Аризоной, команда которой обладала национальной номинацией. Четыре игрока из Аризоны играли в национальной сборной NBA. Однако на половине матча неожиданно для всех Орегон оказался впереди на целых 12 очков. Игроки из Аризоны не могли ничего с этим поделать. Защита Орегона постоянно отражала их атаки. Однако после перерыва Орегон снизил темп игры и стал играть, экономя силы. Они закрывали глаза на медленно сокращающуюся разницу в счете, так как поставили перед собой задачу – просто удержать победу. И, конечно же, эта стратегия не сработала. Аризона немедленно воспользовалась своим преимуществом в опыте и выиграла игру.
Отличие состоит в том, что в одном случае команда играет для того, чтобы выиграть, а в другом случае – для того, чтобы не проиграть. Большинство игроков в мире разработки программного обеспечения, с которыми мне приходилось иметь дело, играют для того, чтобы не проиграть. Изводится масса бумаги. Проводится огромное количество совещаний. Каждый пытается разрабатывать в строгом соответствии с общепринятыми правилами (по книжке) не потому, что в этом есть смысл, а потому, что в конце работы они получат возможность сказать, что это не их вина в том, что все кончилось так плачевно.
Если разработка программного продукта осуществляется для того, чтобы победить, каждый член команды делает все, чтобы помочь команде выиграть и не делает чего‑либо такого, что может помешать этому.
Надежное экспериментирование – каждый раз, когда вы принимаете решение и не тестируете его, существует вероятность, что принятое вами решение неправильно. Чем больше таких решений вы принимаете, тем выше становится эта вероятность. Именно так увеличивается риск. Чтобы снизить риск, результатом сеанса проектирования должен стать не завершенный дизайн, а серия экспериментов, отвечающих на вопросы, которые возникли у вас в процессе проектирования. Результатом обсуждения требований также должна стать серия экспериментов. Каждое абстрактное решение должно быть протестировано.
Открытая честная коммуникация – это настолько очевидный принцип, что я чуть не забыл его упомянуть. Для всех очевидно, что общение должно быть открытым и искренним, однако зачастую приходится сталкиваться с обратным. И это огорчает. Программисты должны быть способны объяснить последствия решений, принимаемых другими людьми. Например: В этом куске кода ты нарушил принцип инкапсуляции, и в результате у меня возникли проблемы. Программисты должны быть способны говорить друг другу о проблемах в коде. Они должны быть способны свободно и без стеснения рассказать о своих страхах и в ответ получить поддержку. Они должны быть способны с легкой душой сообщать заказчикам и менеджерам плохие новости. Они должны делать это как можно раньше, и их не надо за это наказывать.
Если я вижу, как кто‑то, прежде чем ответить на мой вопрос, оглядывается вокруг, чтобы посмотреть, кто его слышит, я воспринимаю это как серьезную проблему всего проекта. Если обсуждаются личные вопросы, я, конечно же, понимаю необходимость некоторой конфиденциальности, однако вопрос о том, какую из двух объектных моделей использовать, не должен быть тайной за семью печатями.
Работа в соответствии с человеческими инстинктами, а не вопреки им – люди любят выигрывать. Люди любят учиться. Люди любят взаимодействовать с другими людьми. Люди любят быть частью команды. Люди любят управлять. Люди любят, когда им доверяют. Люди любят хорошую работу. Люди любят, когда разрабатываемая ими программа отлично работает.
Пол Чисолм (Paul Chisolm) пишет:
Я был на совещании, на котором один так называемый менеджер контроля качества предложил добавить шесть дополнительных полей в состав HTML‑формы, и без того заполненой данными, которые к тому же редко когда использовались. Этот самый менеджер объяснил, что добавление новых полей необходимо не потому, что данная информация окажется полезной в дальнейшем, а потому, что дополнительные поля позволят СЭКОНОМИТЬ ВРЕМЯ. Моя реакция была следующей: я ударил лбом о твердую поверхность стола, за которым проводилось совещание, прямо как мультипликационный герой Warner Brothers, который только что услышал что‑то невероятное. После этого я попросил их перестать мне лгать. На сегодняшний день я не знаю, был ли это наименее профессиональный или, наоборот, наиболее профессиональный поступок в моей жизни. Однако мой глазной врач сказал мне, чтобы я больше не стучал головой о стол, так как при этом сетчатка в моем глазу может отсоединиться от глазного дна.
Пол Чисолм (Paul Chisolm). Источник: электронная почта.
Это достаточно сложно – разработать процесс, в рамках которого краткосрочные личные интересы служат долгосрочным интересам всей команды. Вы можете сколько угодно рассуждать на тему, насколько та или иная методика способствует достижению долгосрочной всеобщей цели, однако как только вы оказываетесь под давлением, вы обнаруживаете, что если методика не способствует решению конкретной проблемы, стоящей перед вами в настоящий момент, вы отбрасываете ее в сторону. Если дисциплина ХР не будет удовлетворять краткосрочным личным интересам людей, она обречена на провал.
Некоторым в ХР нравится именно то, что эта дисциплина создает у программистов ощущение, будто они занимаются именно тем, чем они занимались бы, если бы их никто не заставлял специально заниматься той или иной проблемой. При этом ХР обеспечивает общее развитие проекта в заданном направлении. Мне запомнилась одна образная цитата: ХР соответствует поведению программистов в условиях дикой природы.
Принимаемая ответственность – ничто не может так повредить работе отдельного человека или всей команды, как жесткое указание, чем именно они должны заниматься. Это особенно справедливо, если то, что предлагается сделать, сделать невозможно. Люди работают эффективнее, только если они чувствуют, что занимались бы этой работой, даже если бы никто их к этому не принуждал. Если человеку приказали выполнять некоторую не устраивающую его работу, в ходе своей деятельности он сможет найти множество способов объяснить свое нежелание и несогласие с этим. Все это пагубно повлияет как на его собственную деятельность, так и на деятельность всей команды.
Альтернативой этого является ответственность, которая не вешается на человека в приказном порядке, а принимается им добровольно. Это не означает, что вы всегда занимаетесь только тем, чем вам нравится заниматься. Вы являетесь частью команды, и если команда придет к выводу, что некоторая задача требует решения, должен найтись человек, который возьмется за это вне зависимости от того, насколько отталкивающей для него будет эта задача.
Локальная адаптация – вы должны адаптировать то, о чем вы читаете в данной книге, к своим локальным условиям. Это является применением принципа принимаемой ответственности к используемому вами процессу разработки. Адаптация ХР не означает, что я должен сказать вам, как вы должны разрабатывать программный продукт. Это означает, что вы должны самостоятельно определить, как вы должны разрабатывать программный продукт. Я могу рассказать вам лишь о том, какие методики я проверил на собственном опыте и при этом убедился, что они неплохо срабатывают. Я могу сообщить вам о возможных последствиях в случае, если вы отклонитесь от использования предлагаемых мною методик. В конце концов, это ваш собственный процесс разработки. Сегодня вы должны определить, как он будет происходить. Вы должны убедиться в том, что принятые решения будут исполняться и завтра. Вы должны модифицировать этот процесс и адаптировать его. Вы не должны думать так: Теперь я знаю, как следует разрабатывать программы. Вместо этого вы должны сказать себе: Я должен обдумать все это, а затем уже приступать к программированию. Да, вы должны, но это того стоит.
Путешествие налегке – вы не можете нести с собой гору багажа и при этом двигаться быстро. Вы должны использовать в отношении своего багажа следующие наречия:
• немного;
• просто;
• ценно.
Члены команды ХР должны стать интеллектуальными кочевниками, в любую минуту готовыми быстро упаковать свои пожитки и следовать за пастухом. Пастухом в данном случае является дизайн, который развивается в ином направлении, чем это предполагалось ранее, или заказчик, который хочет развивать проект в ином направлении, чем это предполагалось ранее, или член команды, который решил уйти из проекта, или технология, которая подчас эволюционирует с головокружительной быстротой, или изменяющийся климат, в котором функционирует бизнес. Как все кочевники, члены команды ХР должны привыкнуть путешествовать налегке. Они не должны брать в свое путешествие слишком многого – в багаже не должно оставаться ничего, за исключением того, что необходимо для удовлетворения нужд заказчика, то есть тестов и кода.
Откровенные оценки – наше желание контролировать процесс разработки программного обеспечения ведет нас к необходимости оценки. Эта оценка должна быть достаточно точной. Это хорошо, однако похоже на то, что мы вынуждены оценивать на уровне детализации, который не поддерживается имеющимися у нас инструментами. Если у вас нет надежного способа измерения на таком уровне детализации, то лучше сказать: Это займет две недели, чуть больше или чуть меньше, чем сказать: 14,176 суток. Мы также нуждаемся в единицах измерения, которые соответствуют избранной нами методике работы. Например, количество строк кода становится бессмысленной системой измерения в случае, если код начинает стремительно раздуваться за счет того, что мы обнаружили более эффективные способы программирования.
Глава 9.
Обратно к истокам
Мы хотим сделать все, что от нас зависит, для того чтобы получить стабильный, предсказуемый процесс разработки программного продукта. Однако у нас нет времени на что‑либо лишнее. Четыре основных рода деятельности, которые составляют собой процесс разработки, – это кодирование, тестирование, слушание и проектирование.
Рассказ об управлении автомобилем. Четыре ценности – коммуникация, простота, обратная связь и храбрость. Двойной набор принципов. Теперь мы готовы приступить к формированию дисциплины разработки программного обеспечения. Вначале надо определить круг решаемых нами проблем. К какой области будут относиться наши предписания? Решением проблем какого сорта мы будем заниматься? Проблемы какого сорта будут игнорироваться нами?
Я вспоминаю, как я впервые научился программировать на BASIC. У меня была пара книг, в которых описывались основы программирования. Я достаточно быстро прочитал их и, когда я закончил, решил приступить к решению проблемы, которая была несколько сложнее, чем примитивные примеры, рассматривавшиеся в этих книгах. Я решил написать игру Star Trek (Звездный путь), похожую на ту, в которую я играл в Lawrence Hall of Science в университете Berkeley, только моя версия должна была бы стать круче.
Чтобы решать упражнения из двух изученных мною книг, я использовал следующий процесс разработки программ: в течение нескольких минут я пристально изучал условие задачи, затем писал код для ее решения, а затем решал возникшие в результате выполнения этого кода проблемы. И вот я уселся за компьютер с твердым намерением написать игру. В течение нескольких минут размышлений у меня не родилось ни одной мысли. Я понятия не имел, как написать приложение объемом более чем 20 строк. Я пересел за письменный стол, решив вначале написать всю программу на бумаге и только после этого перенести ее в компьютер. Я набросал три строки, которые я уже набивал на клавиатуре ранее, а затем опять остановился в мучительном размышлении.
Я чувствовал, что надо сделать что‑то еще помимо программирования, но я не знал, что именно.
Что если теперь мы вернемся в то же самое состояние, однако на этот раз на волне обретенного нами опыта? Что мы должны были бы сделать в подобной ситуации? Мы знаем, что нельзя просто кодировать до тех пор, пока все не будет сделано. Какой деятельностью мы должны будем заняться? Что мы должны получить от каждой из этих деятельностей, если мы осваиваем их заново?
Заключение
Итак, вы кодируете потому, что без этого вы вообще не сможете получить какого‑либо результата. Вы тестируете потому, что без этого вы не сможете определить, завершена ли ваша работа. Вы слушаете потому, что без этого вы не сможете понять, что собственно кодировать и что тестировать. Наконец, вы проектируете для того, чтобы получить возможность продолжать кодировать, тестировать и слушать неограниченное время. Вот и все. Именно эти четыре рода деятельности нам и предстоит структурировать в рамках нашей новой дисциплины:
• кодирование;
• тестирование;
• слушание;
• проектирование.
Часть 2.
Глава 10.
Краткий обзор
Мы будем опираться на симбиоз взаимодействующих между собой методик. Методик, некоторые из которых были забыты десятилетия назад как непрактичные и наивные.
Вот исходные материалы, из которых нам предстоит построить новую дисциплину разработки программного обеспечения:
• история об управлении автомобилем;
• четыре ценности – коммуникация, простота, обратная связь и храбрость;
• принципы;
• четыре базовые активности – кодирование, тестирование, слушание и проектирование.
Наша задача – структурировать четыре активности. Мы должны не только структурировать активности, мы должны сделать это в соответствии с длинным списком подчас противоречивых принципов. В то же время мы должны попытаться улучшить экономическую производительность разработки программного обеспечения таким образом, чтобы все получили возможность слушать.
Нет проблем.
Э‑э‑э...
Целью данной книги является объяснение того, как работают входящие в ХР методики, поэтому в данной главе я бегло перечислю основные группы используемых в рамках ХР методик. В следующей главе я покажу, как подобные смехотворно простые решения могут дать столь значительный результат. Там, где некоторая методика слаба, сила остальных методик покрывает недостатки слабой. В последующих главах некоторые темы будут рассмотрены более детально.
Для начала перечислю все методики.
• Игра в планирование (planning game) – быстро определяет перечень задач (объем работ), которые необходимо реализовать в следующей версии продукта. Для этого рассматриваются бизнес‑приоритеты и технические оценки. Если со временем план перестает соответствовать действительности, происходит обновление плана.
• Небольшие версии (small releases) – самая первая упрощенная версия системы быстро вводится в эксплуатацию, после этого через относительно короткие промежутки времени происходит выпуск версии за версией.
• Метафора (metaphor) – эта простая общедоступная и общеизвестная история, которая коротко описывает, как работает вся система. Эта история управляет всем процессом разработки.
• Простой дизайн (simple design) – в каждый момент времени система должна быть спроектирована так просто, как это возможно. Чрезмерная сложность устраняется, как только ее обнаруживают.
• Тестирование (testing) – программисты постоянно пишут тесты для модулей. Для того чтобы разработка продолжалась, все тесты должны срабатывать. Заказчики пишут тесты, которые демонстрируют работоспособность и завершенность той или иной возможности системы.
• Переработка (refactoring) – программисты реструктурируют систему, не изменяя при этом ее поведения. При этом они устраняют дублирование кода, улучшают коммуникацию, упрощают код и повышают его гибкость.
• Программирование парами (pair programming) – весь разрабатываемый код пишется двумя программистами на одном компьютере.
• Коллективное владение (collective ownership) – в любой момент времени любой член команды может изменить любой код в любом месте системы.
• Непрерывная интеграция (continuous integration) – система интегрируется и собирается множество раз в день. Это происходит каждый раз, когда завершается решение очередной задачи.
• 40‑часовая неделя (40‑hour week) – программисты работают не более 40 часов в неделю. Это правило. Никогда нельзя работать сверхурочно две недели подряд.
• Заказчик на месте разработки (on‑site customer) – в состав команды входит реальный живой пользователь системы. Он доступен в течение всего рабочего дня и способен отвечать на вопросы о системе.
• Стандарты кодирования (coding standards) – программисты пишут весь код в соответствии с правилами, которые обеспечивают коммуникацию при помощи кода.
В данной главе кратко рассказывается о том, что подразумевается под каждой из этих методик. В следующей главе (Как это работает?) мы рассмотрим взаимосвязи между методиками, благодаря которым слабость одной методики нейтрализуется силой другой методики.
Глава 11.
Как это работает?
Заключение
Любая из рассмотренных методик сама по себе плохо приспособлена для использования в рамках программистского проекта (за исключением, возможно, тестирования). Чтобы обеспечить их эффективное применение на практике, вы должны использовать их все одновременно. На рис. 4 изображена диаграмма, которая иллюстрирует взаимодействие всех методик.
Линия между двумя практиками указывает на то, что обе эти практики являются поддержкой друг для друга. Я не хотел размещать этот рисунок в самом начале главы, так как при взгляде на него вы могли решить, что ХР – это слишком сложная штука. Отдельные части сами по себе очень просты. Насыщенность и богатство происходят от взаимодействия между составными частями этой дисциплины.
Рис. 4. Диаграмма, иллюстрирующая взаимодействие всех методик
Глава 12.
Стратегия менеджмента
Мы будем осуществлять управление всем проектом, используя при этом базовые приемы бизнес‑менеджмента, – поэтапная поставка, быстрая и надежная обратная связь, ясная взаимосвязь бизнес‑требований к системе, а также использование специалистов для решения специализированных задач.
Дилемма менеджмента состоит в следующем. С одной стороны, было бы неплохо, если бы все решения принимал менеджер. При этом не приходится тратить ресурсы на коммуникацию, так как существует только один человек. Существует один человек, который отвечает за высший менеджмент. Существует один человек, который обладает видением. Никому больше не надо ничего знать, так как все решения принимает только один человек.
Мы знаем, что эта стратегия не срабатывает, так как ни один человек в мире не знает достаточно для того, чтобы принимать качественные решения во всех областях. Стратегии управления, сбалансированные в сторону централизованного контроля, также сложно реализовывать, так как при этом возникает чрезмерная нагрузка на тех, в отношении которых выполняется управление.
С другой стороны, прямо противоположная стратегия также не срабатывает. Вы не можете позволить кому угодно делать, что ему вздумается, без какого‑либо надзора. Люди начнут действовать в разнобой. Требуется кто‑то, кто обладал бы более общим взглядом на проект и мог бы повлиять на его развитие в случае, если работа команды отклоняется от намеченного курса.
И вновь мы должны вернуться к принципам, которые помогут нам проложить путь между двумя крайностями.
• Принимаемая ответственность, – в соответствии с этим принципом обязанность менеджера состоит не в том, чтобы назначить ту или иную работу, тому или иному человеку, а в том, чтобы указать команде на необходимость выполнения этой работы.
• Качественная работа – предполагает, что взаимодействие между менеджерами и программистами должно основываться на доверии, так как программисты хотят делать свою работу хорошо. С другой стороны, это не означает, что менеджер может вообще ничего не делать. Однако необходимо понимать разницу между фразами: Я стараюсь заставить этих ребят делать свою работу хорошо и Я должен помочь этим ребятам делать свою работу еще лучше .
• Постепенное изменение – предполагает, что менеджеры не выдают программистам в самом начале работы над проектом толстое описание внутренней политики, в рамках которой следует выполнять работу, а управляют процессом разработки в течение всего времени работы над проектом.
• Локальная адаптация – предполагает, что менеджеры должны взять на себя адаптацию ХР к локальным условиям, анализируя моменты, в которых культура ХР конфликтует с культурой компании, и формируя решения проблем в случае несоответствия.
• Путешествие налегке – предполагает, что менеджер не создает чрезмерной лишней нагрузки на проект (например, длительные совещания с обязательным присутствием всех членов команды или бесконечные продолжительные доклады о текущем состоянии проекта). Любая просьба, которую менеджер может адресовать программисту, должна требовать не очень много времени для исполнения.
• Откровенные оценки – предполагает, что любые метрики, собираемые менеджером, должны находится на реалистичном уровне точности. Не пытайтесь определять время с точностью до секунды, если у ваших часов есть только часовая и минутная стрелки.
Стратегия, которую можно сформировать на основании всего перечисленного, ближе к децентрализованному принятию решений, чем к централизованному контролю. Работа менеджера – вести игру в планирование (Planing Game) для того, чтобы собирать метрики, делать так, чтобы эти метрики были наблюдаемыми для тех, чья работа подвергается анализу и оценке, и время от времени вмешиваться в ситуации, в которых принятие решения распределенным образом невозможно.
Глава 13.
Стратегия организации рабочего места
Мы создадим для нашей команды открытое рабочее место с небольшими индивидуальными пространствами по периферии и общей областью программирования в середине.
Рон Джеффрис (Ron Jeffries) писал о фотографии, показанной на рис. 5.
На этой фотографии показано рабочее помещение команды DaimlerChrysler C3, работающей над проектом Payroll. В помещении находятся два больших стола, на каждом из которых установлено по шесть программистских компьютеров. Пары программистов располагаются за любыми доступными для этого компьютерами. На картинке ничего не срежиссировано специально: программисты действительно работают за одним компьютером в паре, именно так, как показано. Тот, кто фотографировал, на самом деле работает в паре с Четом – программистом, который сидит за дальним столом спиной к фотокамере.
На двух видимых на фотографии стенах размещаются белые доски, на которых показаны функциональные тесты, требующие внимания, запланированные сеансы CRC, а также план итераций на задней доске. Листки бумаги, которые можно заметить в верхней части доски слева, – это небольшие заметки, в которых отмечены используемые группой правила ХР.
Вдоль правой стены располагаются небольшие отгороженные от остального помещения индивидуальные ячейки, в которых можно поставить телефон или использовать их для того, чтобы написать что‑нибудь на бумаге, не отвлекаясь на других людей.
В дальней части помещения, между компьютерным столом и белой доской, располагается стандартный стол, вокруг которого команда собирается для CRC‑сеансов. Как правило, стол завален карточками CRC и едой (одно из используемых командой правил гласит: здесь должна быть еда).
Помещение было спроектировано командой: мы действительно РЕШИЛИ работать в этом помещении. Люди говорят негромко, поэтому уровень шума на удивление низкий. Однако если вы нуждаетесь в помощи, вы можете немножко повысить голос, чтобы получить эту помощь. Помощь придет незамедлительно: обратите внимание, что на полу отсутствует ковер. Это значит, что стулья, на которых мы сидим, могут перемещаться по комнате без каких‑либо затруднений.
Рон Джеффрис (Ron Jeffries)
Рис. 5. Рабочее помещение команды DaimlerChrysler СЗ
Если у вас нет подходящего места для работы, ваш проект не сможет стать успешным. Различие между хорошим местом для команды и плохим местом для команды значительно и подчас критично.
В моей карьере консультанта был момент, когда я особенно остро ощутил значимость правильной организации рабочего места. Я был приглашен в одну организацию для того, чтобы пересмотреть объектно‑ориентированный дизайн для некоторого проекта. Я взглянул на систему и, конечно же, обнаружил, что она была спроектирована из рук вон плохо. После этого я обратил внимание на то, кто где сидит. Команда состояла из четырех старших программистов. Каждый из них работал в своем собственном кабинете, а каждый из этих кабинетов располагался в одном из четырех углов здания средних размеров. Я посоветовал им переселиться так, чтобы их кабинеты располагались рядом друг с другом. Я был приглашен из‑за того, что обладал значительным опытом в области Smalltalk и объектно‑ориентированного дизайна, однако, на мой взгляд, наиболее ценным советом, который я им дал, было предложение переставить мебель.
Правильная организация рабочих помещений – это в любом случае непростая работа. В этой области существует большое количество конфликтующих ограничений. Планировщики рабочих помещений стараются потратить как можно меньше денег и при этом обеспечить как можно большую гибкость. Люди, использующие эти помещения, желают работать в тесной связке с остальной командой. В то же время они нуждаются в некотором отделенном от остальных людей индивидуальном пространстве, из которого они могли бы (например) звонить в приемную своей поликлиники.
В рамках ХР существует сильная склонность к огромным публичным пространствам. ХР – это коммунальная дисциплина разработки программного обеспечения. Члены команды должны видеть друг друга, слышать изредка выкрикиваемые вопросы, случайно подслушивать сторонние переговоры, в которые они могли бы внести жизненно важные замечания.
ХР преображает структуру рабочих помещений. Общепринятая структура офисов плохо соответствует идеологии ХР. Например, если вы поставите свой компьютер в угол, это будет не самым удачным решением, так как двум людям будет неудобно работать с таким компьютером. Часто рабочее помещение – это огромный зал, поделенный перегородками на небольшие индивидуальные рабочие ячейки, однако такая структура тоже не работает в рамках ХР. Для повышения эффективности ХР необходимо снизить высоту стен по крайней мере на половину, а лучше вообще от них избавиться. В то же время команда должна быть отделена от остальных команд.
Лучшим является план помещения, в котором центральное обширное общее пространство обрамлено по периметру небольшими отгороженными ячейками. Члены команды могут хранить в этих ячейках свои личные вещи, делать в них телефонные звонки, или проводить в них время в одиночестве, когда они не хотят, чтобы их отвлекали. Вся остальная команда должна с уважением относиться к виртуальному одиночеству человека, сидящего в собственной ячейке. Самые большие, самые быстрые компьютеры следует разместить в середине центрального общего пространства (индивидуальные ячейки могут быть как с компьютерами, так и без компьютеров). В этом случае, если кто‑то хочет приступить к программированию, он будет вынужден выйти на открытое общее пространство. Здесь каждый может увидеть, что происходит; формирование пар осуществляется без затруднений и каждая пара получает дополнительную энергетику от других пар, которые также занимаются программированием поблизости.
Если у вас есть возможность, вы можете зарезервировать наиболее уютный кусочек помещения рядом с общим рабочим пространством, разместить там кофейный комбайн, пирожки, несколько игрушек, нечто, что будет притягивать туда людей. Очень часто для того, чтобы выйти из тупика, который возник в процессе разработки, достаточно отойти ненадолго в сторону и отвлечься. Если при этом у команды будет специально предназначенное место, люди с большей вероятностью воспользуются этим в случае необходимости.
Одна из рассмотренных ранее ценностей – храбрость – находит свое воплощение в тяге ХР к рабочим помещениям. Если корпоративный взгляд на планировку рабочего пространства конфликтует со взглядом команды, команда, как правило, побеждает. Если компьютеры размещены в неправильных местах, они перемещаются в новые места. Если помещение разделено перегородками неправильно, перегородки исчезают.
Если освещение слишком яркое, оно приглушается. Если телефоны звонят слишком громко, однажды обнаруживается, что в звонке каждого из них набита вата.
Однажды мы работали для банка, и когда я в самый первый день пришел на работу, я обнаружил, что для работы нам выделили отвратительные старые столы, за каждым из которых мог разместиться только один человек. По обе стороны от каждого стола были смонтированы металлические выдвижные ящики, таким образом, столы даже нельзя было сдвинуть вместе. Между выдвижными ящиками умещались ноги только одного человека. Очевидно, что с этим невозможно было работать. Мы посмотрели вокруг и обнаружили электрическую отвертку с достаточно мощным двигателем. После этого мы отвинтили у одного из столов один набор выдвижных ящиков. В результате за этим столом теперь могли разместиться не один, а два человека. Аналогичным образом мы обработали все остальные столы.
Вся подобная возня с мебелью может стать для вас причиной дополнительных административных проблем. Люди, в обязанности которых входит следить за состоянием рабочих помещений и инвентаря, могут прийти в негодование от того, что кто‑то без их ведома передвигает столы (не думая о том, что если обратиться к ним с этой просьбой, то ее исполнение может потребовать несколько недель или даже месяцев). На это я отвечу: Очень плохо. Я должен разработать программную систему, и если я избавлюсь от этих дурацких перегородок, я смогу справиться с моей задачей лучше и быстрее, поэтому я иду и убираю то, что мешает мне работать. Если организация, для которой я работаю, не может вытерпеть столь смелую инициативу, значит, я просто не хочу для нее работать.
Если вам удается установить контроль над физическим окружением, это значит, что ваша команда получает чрезвычайно важное сообщение: никто не собирается смиряться с какими бы то ни было иррациональными интересами организации, которые встают на пути к успеху. Установление контроля над физической средой – это первый шаг в направлении установления контроля над общим стилем работы команды.
Мебель и рабочие помещения могут быть предметом постоянного экспериментирования (еще одна ценность – обратная связь – в действии).
В конце концов, организация потратила кучу денег на приобретение всего этого гибкого офисного инвентаря. Все эти деньги будут потрачены впустую, если вы не воспользуетесь этой гибкостью и не перенастроите свой офис так, как вам это нужно. Что, если сделать индивидуальные ячейки ближе друг к другу? А что, если их немножко удалить? Может, поставить компьютер, предназначенный для интеграции, в центре зала? А может, лучше в углу? Попробуйте это. То, что оказывается удобным, остается. Тем, что не работает, жертвуют в процессе следующего эксперимента.
Глава 14.
Разделение полномочий между технарями и бизнесменами
Одним из основополагающих правил нашей стратегии является то, что технари концентрируются на решении технических проблем, а бизнесмены – на решении бизнес‑проблем. Проект должен управляться бизнес‑решениями, однако для принятия бизнес‑решений должна использоваться информация о затратах и риске, предоставляемая техническими специалистами. Эта информация является результатом технических решений.
Существуют два широко распространенных неправильных режима взаимоотношений между бизнесом и разработчиками: когда либо бизнес, либо разработчики получают слишком большую власть над проектом, проект начинает страдать.
Бизнес
Когда бизнесмены получают слишком много полномочий, они начинают диктовать разработчиком значения для всех четырех переменных. Вот то, что ты должен сделать. Это должно быть сделано тогда‑то и тогда‑то. Нет, тебе не дадут ни одной дополнительной рабочей станции. И для тебя будет лучше, если ты сделаешь эту работу с наивысшим возможным качеством, иначе у тебя будут проблемы. Ты меня хорошо понял? Скотина ленивая!
В такой ситуации бизнес предписывает слишком многое. Некоторые элементы в списке требований абсолютно обязательны, но некоторые – нет. И если у разработчиков не будет никаких полномочий, они не смогут возразить. Они не смогут принудить бизнес выбрать правильный вариант. И тогда разработчики, понурив голову, идут работать над невыполнимой задачей, которую перед ними поставили.
Как правило, наименее важные требования являются причиной наибольшего риска. Похоже, это является следствием их природы. Они меньше всего обдумываются, меньше всего анализируются и меньше всего осмысливаются, поэтому вероятность того, что именно они изменятся в процессе разработки, выше всего. Очень часто такие требования оказываются также наиболее рискованными с технической точки зрения.
В результате, если бизнес получает слишком большие полномочия, проект требует слишком много усилий и генерирует слишком много риска, при этом он обеспечивает слишком незначительную отдачу.
Глава 15.
Стратегия планирования
Мы будем планировать нашу работу следующим образом: сначала мы быстро сформируем общий план, затем мы будем постоянно пересматривать его, формируя более конкретные цели для более коротких сроков: лет, месяцев, недель и дней. Мы будем формировать план быстро и с минимальными затратами, поэтому если нам потребуется изменить его, мы должны будем преодолеть минимальную инерцию.
Планирование – это процесс предположения, как будет выглядеть процесс разработки программного продукта для заказчика. Вот некоторые цели, которые достигаются в процессе планирования:
• Собрать команду вместе;
• Определить объем работ и приоритеты;
• Оценить затраты и график работ;
• Добиться появления у каждого заинтересованного лица ощущения того, что система действительно может быть реализована;
• Определить исходные данные для обратной связи.
Давайте взглянем на принципы, которые влияют на планирование. Некоторые из них являются базовыми принципами, о которых шла речь в главе 8. Другие относятся конкретно к планированию.
• Планируйте только то, что вам нужно для реализации очередного этапа – на любом уровне детализации осуществляйте планирование только очередного этапа работ – то есть следующей версии, завершения следующей итерации. Это не означает, что вы не должны выполнять долгосрочное планирование. Вы можете это делать, только не с высокой степенью детализации. Вы можете спланировать текущую версию достаточно скрупулезно, и при этом вы можете обрисовать план пяти следующих версий набором простых тезисов. При этом вам не придется тратить значительных усилий на то, чтобы спланировать все шесть версий с высокой степенью детализации.
• Принимаемая ответственность – ответственность может быть только принята, но не может быть назначена. Это означает, что в рамках ХР не может быть такой вещи, как планирование сверху вниз. Менеджер не может прийти к команде и сказать: Вот то, что мы должны сделать и это должно быть сделано за такое‑то и такое‑то время . Менеджер проекта должен предложить команде взять ответственность за выполнение работы. После этого он должен внимательно выслушать ответ.
• Предположительные оценки должны выполняться лицом, ответственным за реализацию, – если команда берет на себя ответственность за выполнение некоторой работы, она должна сообщить, какое время для этого потребуется. Если член команды берет на себя ответственность за решение некоторой задачи, он должен сообщить, сколько ему для этого потребуется времени.
• Игнорируйте взаимосвязи между частями проекта – планируйте так, как если бы части разработки можно было бы менять между собой по вашему собственному желанию. Это простое правило избавит вас от проблем при условии, что вы будете в первую очередь реализовывать наиболее высокоприоритетные бизнес‑требования. Сколько стоит кофе? 25 центов за чашку, но вторая чашка бесплатно. Тогда дайте мне вторую чашку. Подобные ситуации не должны происходить.
• Планируйте в соответствии с определенной целью: для определения приоритета или для осуществления разработки – не забывайте о том, зачем вы планируете. Если вы планируете для того, чтобы заказчик мог определить приоритеты, вы можете делать это с меньшей детализацией. Если же вы планируете для осуществления реализации, где вы должны проанализировать специфические тестовые случаи, вам потребуется существенно более высокий уровень детализации.
Цель
Цель игры – максимизировать ценность программного обеспечения, разработкой которого занимается команда. Исходя из ценности программы вы можете получить затраты, связанные с ее разработкой, а также уровень риска, которому вы подвергаетесь в процессе разработки.
Куски
Куски (pieces) в игре в планирование – это карточки историй (story cards). Пример одной из них показан на рис. 6.
Рис. 6. Карточка с историей (story card)
Игроки
В игру в планирование играют два игрока – бизнес (Business) и разработчики (Development). Разработчики – это люди, которые отвечают за реализацию системы. Бизнес – это люди, которые принимают решения о том, что должна делать система.
Иногда сразу ясно, кто именно должен играть на стороне бизнеса. Если компания – биржевой брокер платит деньги за разработку специализированного программного обеспечения, значит, эти люди играют на стороне бизнеса. Именно они должны определить, что необходимо сделать в первую очередь. Но если вы занимаетесь разработкой программного продукта, который предназначен для массового рынка? Кто тогда играет роль бизнеса? Бизнес должен принимать решения относительно объема работ, приоритетов и содержимого версий продукта. Все эти решения, как правило, делаются сотрудниками отдела маркетинга. Если это достаточно умные люди, они будут принимать решения исходя из мнения:
• реальных пользователей продукта;
• заинтересованных в продукте групп;
• людей, занимающихся продажами.
Лучше всего на стороне бизнеса играют пользователи‑эксперты. Например, в свое время я работал над созданием системы обслуживания клиентов для финансового фонда взаимных вкладов. На стороне бизнеса играла женщина‑руководитель отдела работы с клиентами, которая в свое время, в самом начале своей карьеры, в течение долгих лет работала в качестве обычного клерка со старой компьютерной системой. Она изучила ее во всех подробностях. Время от времени у нее возникали проблемы, связанные с тем, что она не могла отличить то, что должна делать новая система, от того, что делала старая. Однако после того, как она привыкла к составлению историй, она отлично освоилась.
Ходы
Игра состоит из трех фаз:
• исследование (exploration) – в этой фазе необходимо определить, что нового должна делать система;
• подтверждение (commitment) – в этой фазе необходимо решить, какое подмножество всех возможных требований необходимо удовлетворить в следующую очередь;
• управление (steer) – в этой фазе необходимо управлять разработкой по мере того, как реальность вносит свои коррективы в план.
Ходы в составе некоторой фазы, как правило, делаются именно в этой фазе, однако вообще‑то это не обязательно. Например, в ходе фазы управления можно писать новые истории. Кроме того, смена фаз осуществляется циклически: после того, как вы в течение некоторого времени находитесь в фазе управления, необходимо вновь вернуться к исследованию.
Глава 16.
Стратегия разработки
В отличие от стратегии менеджмента стратегия разработки радикально отличается от того, что принято считать общепризнанной мудростью, – мы будем тщательно формировать решение сегодняшней проблемы именно сегодня в надежде на то, что мы всегда сможем решить завтрашнюю проблему завтра.
В ХР метафора программирования используется для всех видов деятельности, благодаря чему все, чем вы занимаетесь, выглядит как программирование: программирование в ХР выглядит как программирование с некоторыми небольшими добавлениями, например, автоматическим тестированием. Однако разработка, как и все остальное в ХР, может показаться простой только на первый взгляд. Все составные части достаточно просты, чтобы их объяснить, однако использовать их совместно достаточно сложно. Как только вы начинаете практиковать ХР, у вас появляется страх. Как только появляется давление, возвращаются старые привычки.
Стратегия разработки начинается с планирования итерации. Постоянно выполняемая интеграция уменьшает количество конфликтов и является естественным завершением эпизода разработки. Коллективное владение стимулирует всю команду делать всю систему все лучше и лучше. Наконец, программирование парами связывает весь процесс в единое целое.
Глава 17.
Стратегия проектирования
Мы начнем с самого простого дизайна, который только возможен. После этого мы будем постоянно пересматривать дизайн системы. Мы будем удалять из системы любую гибкость, которая оказывается бесполезной.
Во многих отношениях эта глава оказалась для меня самой сложной из всей книги. Стратегия дизайна в ХР предусматривает, что система всегда должна обладать наиболее простым дизайном, при которым срабатывает текущий набор тестов.
Рассмотрим подробнее, что такое простота и что такое наборы тестов.
Глава 18.
Стратегия тестирования
Мы будем писать тесты перед тем, как приступить к кодированию. Это будет происходить каждый раз, когда мы будем садиться за решение очередной задачи. Мы сохраним эти тесты навечно и будем запускать их все вместе очень часто. Мы также будем писать тесты с точки зрения заказчика.
Какая жалость! Никто не хочет разговаривать о тестировании. Тестирование – это гадкий утенок индустрии разработки программного обеспечения. Проблема состоит в том, что каждый знает о важности тестирования. Каждый знает о том, что делает тестирование недостаточно хорошо. И мы видим это – наши проекты не реализуются так, как нам хотелось бы, и мы чувствуем, что тестирование в большем объеме может помочь решению проблемы. Но после этого мы беремся за чтение книги, посвященной тестированию, и увязаем в огромном количестве методик и разновидностей тестирования. Ни за что на свете нам не удастся выполнить все эти предписания и при этом завершить работу в срок.
В ХР тестирование выглядит следующим образом. Каждый раз, когда программист пишет некоторый код, он думает, что этот код будет работать. Каждый раз, когда программист думает, что некоторый код будет работать, он берет свою уверенность из вселенского эфира и воплощает ее в артефакт, который становится частью программы. Теперь уверенность внутри, и программист может ею пользоваться. А так как уверенность теперь внутри программы, остальные люди могут также воспользоваться этой уверенностью.
То же самое можно сказать и о заказчике. Каждый раз, когда заказчик думает о чем‑то конкретном, что должна делать программа, он превращает это в еще один кусок уверенности и размещает его внутри программы. Теперь уверенность заказчика тоже находится внутри программы рядом с уверенностью программиста. Общая уверенность в работоспособности программы со временем все увеличивается и увеличивается.
Теперь вы можете взглянуть на тестирование в ХР и хихикнуть: ведь это не работа для тех, кто любит тестирование, наоборот, это работа для тех, кто любит заставлять программы работать. Вы пишете тесты, которые помогают вам добиться работоспособности создаваемых вами программ, а также обеспечить работоспособность программ, которые вы модифицируете. И ничего больше.
Вспомните принцип: Работать совместно с человеческой природой, а не вопреки ей. С этим связана фундаментальная ошибка, которая присутствует во всех книгах по тестированию, которые я прочитал. Все подобные книги начинаются с предположения, что тестирование – это центр разработки. Вы должны сделать этот тест и тот тест и, о да, конечно, вон тот тест тоже. Если мы хотим, чтобы программисты и заказчики писали тесты, мы должны сделать процесс разработки настолько безболезненным, насколько это возможно. Мы должны рассматривать тесты как инструмент разработки. Тесты – это инструмент, помогающий понять поведение системы, а поведение системы формируется разработчиками, а не самими тестами. Если бы было возможно осуществлять разработку без тестов, мы могли бы выбросить все тесты в одну минуту.
Массимо Арнольди (Massimo Arnoldi) пишет:
К сожалению, по крайней мере для меня (и не только), тестирование – это нечто противоречащее человеческой природе. Где‑то очень глубоко в каждом из нас сидит грязная неряшливая свинья, и если ее выпустить на свободу, мы будем писать программы совсем без тестов. Спустя некоторое время после этого у нас внутри победу одерживает рациональная сторона, мы останавливаемся и начинаем писать тесты. Следует обратить внимание, что программирование в паре снижает риск пробуждения свиньи, так как маловероятно, что в одно и то же время свиньи проснутся в обоих партнерах одновременно.
Массимо Арнольди (Massimo Arnoldi). Источник: электронная почта.
Тесты, которые необходимо писать в рамках ХР, являются изолированными и автоматическими. Во‑первых, каждый тест никак не взаимодействует с остальными тестами, которые вы пишете. Таким способом вы избегаете ситуации, когда сбой в одном из тестов является причиной несрабатывания сотен других тестов. Ничто не разочаровывает нас так сильно, как ложные негативные результаты. Утром вы приходите на работу, обнаруживаете огромное количество дефектов, и у вас в кровь выделяется огромное количество адреналина. А потом обнаруживается, что весь этот ворох проблем решается при помощи коррекции одного из тестов. Будете ли вы относиться к тестам с должным вниманием после того, как описанное произойдет с вами пять или десять раз? Нет.
Во‑вторых, тесты автоматические. Тесты наиболее полезны тогда, когда уровень стресса повышается, когда люди работают слишком много, когда человеческий здравый смысл начинает ослабевать. В подобных ситуациях было бы неплохо обладать быстрым и простым способом проверки работоспособности системы. Именно поэтому тесты работают автоматически – вы запускаете их и фактически сразу же получаете короткий односложный ответ: система работает корректно или система работает некорректно.
Протестировать абсолютно все невозможно – для этого тесты должны быть столь же сложными и столь же беззащитными перед ошибками, как и сам код приложения. Ничего не тестировать (в смысле изолированных автоматических тестов) – это самоубийство. Но тогда из всех вещей, которые можно протестировать, что именно вы должны тестировать?
Вы должны тестировать вещи, которые могут не сработать. Если код настолько прост, что он просто не может работать некорректно, и вы видите, что на практике данный код всегда срабатывает, тогда вы можете не писать для него код. Если бы я сказал вам, что надо тестировать абсолютно все, в скором времени вы пришли бы к выводу, что большая часть тестов, которые вы пишете, на самом деле бесполезна, и, если в этом отношении вы схожи со мной, вы перестали бы их писать. Эти тесты предназначены для идиотов!
Тестирование – это ставка. Ставка, которая оправдывает себя в случае, если оказывается, что ваши ожидания не соответствуют действительности. Тест может оправдать свое создание в ситуации, когда он срабатывает при том, что вы не ожидали, что он будет срабатывать. В этом случае вы должны выяснить, почему он срабатывает, так как код умнее, чем вы. Еще одна ситуация, в которой тест оправдывает свое создание, это когда тест не срабатывает, а вы ожидали, что он должен сработать. Очевидно, что в этом случае вы также должны разобраться, в чем дело. В обоих случаях вы узнаете кое‑что новое о разрабатываемой вами программе. Разработка программного обеспечения – это получение новых знаний. Чем больше вы знаете, тем лучше вы разрабатываете код.
Таким образом, если у вас есть такая возможность, вы должны писать только те тесты, которые оправдывают затраты на свою разработку. Однако вы не можете заранее знать, какие из тестов оправданы, а какие – нет (если бы вы знали, это означало бы, что все необходимые знания у вас уже есть и вам не нужно узнавать ничего нового), поэтому вы должны разрабатывать тесты, которые могут оказаться оправданными. По мере того, как вы пишете тесты и выполняете тестирование, вы анализируете, какие разновидности тестов чаще оказываются оправданными, а какие – нет, и с течением времени вы начинаете писать все больше оправданных тестов и все меньше неоправданных.
Часть 3.
Реализация ХР
В данной части книги мы обсудим практическое применение стратегий, описанных в предыдущей части. После того, как вы выбрали упрощенный набор стратегий, вы получаете значительно большую гибкость, с которой вы можете их использовать. Вы можете использовать эту гибкость для многих целей, однако прежде всего вы должны знать о том, что эта гибкость существует, и о том, какие возможности она перед вами открывает.
Глава 19.
Внедрение ХР
Внедрять ХР необходимо по одной методике за раз, всегда выбирая при этом наиболее серьезную проблему, которая стоит перед командой. Как только решаемая проблема перестает быть наиболее серьезной, вы переходите к следующей проблеме.
За простой и, очевидно, корректный ответ на вопрос о том, как следует внедрять ХР, я хочу поблагодарить Дона Уэллса (Don Wells):
1. Выберите самую неприятную для вас проблему.
2. Решите ее, применяя способ ХР.
3. Когда эта проблема перестает быть самой неприятной для вас, повторите эту последовательность действий с самого начала.
Две очевидные составляющие, с которых можно начать процесс внедрения, – это тестирование и игра в планирование. Очень многие проекты страдают от проблем, связанных с низким качеством кода, а также от дисбаланса полномочий между бизнесом и разработчиками. Вторая книга из серии книг, посвященных ХР, под названием Extreme Programming Applied: Playing to Win (Применение экстремального программирования: игра чтобы победить) будет посвящена именно этим темам, так как с освоения именно этих компонентов ХР удобнее всего приступать к внедрению этой дисциплины.
У описанного подхода к освоению ХР существует большое количество преимуществ. Он настолько прост, что даже я могу понять его (после того, как Дон втолковал мне его суть). Вы овладеваете одной методикой за один раз, поэтому вы можете достаточно подробно изучить каждую из этих методик. Вы начинаете с решения наиболее актуальных для вас проблем, и поэтому у вас есть сильная мотивация, стимулирующая желание изменить все к лучшему, и, кроме того, вы немедленно получаете позитивную отдачу в ответ на ваши усилия.
Когда вы решаете наиболее мешающую вам проблему, вы также устраняете один из недостатков ХР: один размер предназначен для всех. Если вы занимаетесь изучением одной из входящих в ХР методик, вы получаете возможность адаптировать ее для конкретно вашей ситуации. Если в некоторой области у вас нет никакой проблемы, вы даже и не подумаете о том, что в этой области ХР можно использовать для решения какихлибо проблем.
Приступая к внедрению ХР, не стоит недооценивать важность физического окружения, даже если ранее вы не имели никаких проблем в этой области. Лично я часто начинаю работу над проектом ХР при помощи электрической отвертки и разводного ключа. Я также рекомендую добавить к описанному ранее процессу два дополнительных этапа:
‑1. Переставьте мебель так, чтобы было удобно программировать парами и чтобы рядом с вами мог сесть заказчик.
0. Купите какую‑нибудь закуску, например шоколадки, сухарики или крекеры.
Глава 20.
Адаптация ХР для существующего проекта
Проекты, в которых требуется изменить существующую культуру, встречаются гораздо чаще, чем проекты, в которых новую культуру необходимо сформировать с нуля. Внедряйте ХР в рамках существующего проекта понемногу, начиная с тестирования или планирования.
Освоение ХР с совершенно новой командой – это не так‑то просто. Внедрение ХР в уже существующих рабочих условиях, с существующей командой и существующим обширным кодом еще сложнее. Перед вами стоят все уже существующие у вас проблемы – обучение навыкам, инструктаж, обеспечение работы над проектом. Также вы обязаны обеспечить функционирование программного обеспечения, которое уже эксплуатируется в рабочих условиях. Это программное обеспечение разработано без учета ваших новых стандартов. Скорее всего, оно обладает значительно более сложной структурой, чем это требуется. Очевидно, оно не тестировалось в такой степени, в которой это требуется в рамках ХР. Если вы собираетесь сформировать новую команду, вы можете выбрать тех людей, кто действительно хочет попробовать ХР. Однако если вы имеете дело с уже существующей командой, возможно, в ней окажется несколько скептически настроенных членов. И вдобавок ко всем этим неприятностям все столы в рабочем помещении уже давно расставлены, и вы даже не имеете возможности организовать программирование парами.
Для адаптации ХР в рамках существующего проекта вам потребуется больше времени, чем если бы вы занимались этим совместно с новой командой, приступая к работе над новым проектом. Это плохие новости.
Однако есть и хорошие новости. Существуют риски, с которыми вынуждены столкнуться люди, которые организуют ХР с нуля, и с которыми вам не придется столкнуться. Вы не окажетесь в рискованной ситуации, в которой вы думаете, что у вас есть отличная идея программы, но со всей уверенностью вы об этом сказать не можете. Вы также не окажетесь в рискованной позиции, в которой вам будет необходимо делать множество решений без немедленной и жизненно‑важной обратной связи с реальными заказчиками.
Я разговаривал со многими командами, которые говорили: О, да! Мы уже работаем в рамках ХР. У нас все, как в ХР. Все, за исключением тестирования. Тестирование мы делаем по старинке. Да, и еще у нас есть 200 страничный документ, в котором изложены точные требования заказчика. Но все остальное мы делаем в точности как в ХР. Именно поэтому данная глава состоит из нескольких разделов, каждый из которых соответствует одной из методик. Если вы уже внедрили у себя одну из методик, которая используется в рамках ХР, вы можете игнорировать соответствующий раздел. Если вы намерены внедрить у себя какую‑то новую методику, обратитесь к соответствующему разделу.
Каким образом можно внедрить ХР с уже существующей командой и программным продуктом, который уже эксплуатируется на производстве? Вы должны модифицировать стратегию адаптации в следующих областях:
• тестирование;
• проектирование;
• планирование;
• менеджмент;
• разработка.
Глава 21.
Жизненный цикл идеального ХР‑проекта
Идеальный проект ХР проходит сквозь короткую стадию начальной разработки, за которой следуют годы поддержки эксплуатации системы на производстве и одновременно пересмотра и переделки. Наконец, когда проект теряет актуальность, он элегантно отправляется в отставку.
В данной главе дается представление о полном жизненном цикле проекта ХР – его истории от начала до конца. История идеализирована – я полагаю, что на текущий момент вы уже поняли, что никаких два проекта ХР не могут (да и не должны) быть абсолютно одинаковыми. В данной главе дается представление о фазах жизни проекта.
Смерть
Хорошо умереть – это также важно, как и хорошо жить. Для ХР это является такой же истиной, как и для людей.
Если заказчик больше не может придумать ни одной новой истории, значит, наступило время хорошенько посыпать систему нафталином. Теперь необходимо написать пяти‑, может быть, десятистраничное описание системы – документ, который может вам потребоваться в случае, если через пять лет вы захотите что‑то изменить внутри.
Это хорошая причина для того, чтобы умереть, – заказчик доволен системой и не может придумать ничего, что можно было бы добавить в систему в обозримом будущем (я никогда с таким не сталкивался, однако я слышал об этом, поэтому я рассматриваю этот вариант для полноты картины).
Существует также и другая, не очень хорошая причина для смерти – система находится в неудовлетворительном состоянии. Заказчик нуждается в новых возможностях, а вы не можете добавить их по экономическим соображениям. Количество дефектов может вырасти до величины, которая является неприемлемой.
Это смерть от энтропии, с которой вы боретесь как можно более долгое время. ХР – это не волшебство. Проекты ХР подвержены энтропии точно так же, как и любые другие проекты. Вы просто надеетесь, что это произойдет как можно позже.
В любом случае, мы столкнулись с невозможным – система должна умереть. Когда это происходит, глаза всех участников проекта должны быть открыты. Команда должна быть в курсе экономической ситуации. Команда, заказчики и менеджеры должны согласиться с тем, что ни команда, ни система не могут выдать заказчику то, что ему нужно.
Теперь наступает время нежного прощания. Устройте вечеринку. Пригласите всех, кто работал над проектом. Это должен быть вечер воспоминаний. Воспользуйтесь возможностью и попытайтесь проанализировать причины того, что система погибла. Благодаря этому вы сможете лучше понять, с чем вам, возможно, придется иметь дело в будущем. Вместе с командой подумайте о том, как именно следует изменить свои действия, чтобы добиться успеха при работе над следующим проектом.
Глава 22.
Роли для людей
Для того чтобы команда ХР могла работать, необходимо, чтобы кто‑то взял на себя исполнение некоторых определенных ролей: программиста, заказчика, инструктора, ревизора.
Спортивная команда играет лучше, если каждый игрок берет на себя исполнение определенной роли. Например, в состав футбольной команды, как правило, входит вратарь, нападающий, защитник и так далее. В баскетбольной команде присутствуют центр, нападение, защита и так далее. Игрок, играющий в одной из этих позиций, принимает на себя определенный набор обязанностей – помощь своим соратникам в нападении, защита от нападения соперников, возможно, контроль над определенным участком поля. Некоторые из этих ролей предусматривают действия в индивидуальном порядке. Другие созданы для исправления ошибок других игроков команды и координации их действий.
Подбор этих ролей основан на опыте и зачастую определяется в правилах игры. Это сделано потому, что данная комбинация ролей признана наиболее эффективной. Возможно, когда‑то давно люди пробовали другие комбинации распределения обязанностей между игроками. Но то, что мы видим сегодня, сохранилось благодаря тому, что именно такая комбинация оказалась более эффективной, чем другие.
Хорошие тренеры учат игроков хорошо исполнять возложенные на них обязанности, иными словами, хорошо играть свою роль. Тренер наблюдает за поведением игрока, указывает на отклонения и либо помогает игроку скорректировать свое поведение, либо объясняет, почему игрок может вести себя несколько иначе.
Однако самый лучший тренер знает, что распределение ролей основано на опыте и не является неизменным законом природы. Время от времени игра меняется или игроки изменяются настолько, что появляется возможность добавить в существующий расклад новые роли или удалить из команды устаревшие, ставшие ненужными позиции. Гениальный тренер всегда следит за тем, какие преимущества появятся у команды в случае, если добавить новую роль или избавиться от одной из существующих.
Еще одна способность, которой обладают великие спортивные тренеры, – это их способность формировать систему в соответствии с командой, а не наоборот. Если у вас есть система, которая работает превосходно в случае, если вы используете быстрых игроков, и если команда, с которой вы работаете, показала себя на тренировках малоподвижной, но взамен этого сильной и выносливой, для вас будет лучше разработать новую систему, которая позволила бы вашей команде в полной мере проявить присущие ей таланты. Большинство тренеров не владеют этим. Вместо этого они настолько фокусируются на красоте системы, что подчас не замечают, что она не срабатывает.
Все это должно служить большим предупреждением для тех, кто слишком сильно привыкает к условиям, которые кажутся ему идеальными. Существуют роли, которые хорошо работали в предыдущих проектах. Если сейчас у вас в распоряжении люди, которые не соответствуют этим ролям, измените роли. Не пытайтесь менять людей (по крайней мере слишком значительно). Не следует действовать так, как будто никакой проблемы нет. Если роль предписывает, что этот человек должен быть склонен к большому риску, и вместо этого вы имеете дело со скрупулезным дотошным человеком, который все привык рассчитывать заранее и не предпринимает никаких действий, не взвесив все за и все против, вы должны найти иное разделение обязанностей, которое будет соответствовать поставленной перед вами цели, но без этой самой роли, которую должен играть рисковый человек.
Например, в свое время я общался с одним менеджером. Разговор шел о его команде. В ней программист являлся также и заказчиком. Я сказал моему собеседнику, что это не может эффективно работать, так как программист должен исполнять процесс и принимать технические решения. При этом необходимо, чтобы бизнес‑решения принимались отдельно – заказчиком (см. описание игры в планирование).
Менеджер стал со мной спорить: Этот парень реальный биржевой брокер, выяснилось, что он умеет также и программировать. Другие брокеры любят и уважают его. Они уверены в нем и желают видеть его в качестве своего доверителя. Он обладает четким представлением о том, в каком направлении должна развиваться система. Другие программисты хорошо различают, когда он разговаривает от лица заказчика и когда он разговаривает от лица технического специалиста .
Хорошо. Правила утверждают, что программист не может быть заказчиком. В данном случае эти правила не применяются. Но по‑прежнему остается в силе принцип разделения технических решений и бизнес‑решений. Вся команда, сам программист/заказчик, и особенно инструктор ХР, должны точно знать, какую роль играет программист/заказчик в каждый конкретный момент времени. Кроме того, инструктор должен знать, что вне зависимости от того, насколько хорошо данная организация работала в прошлом, если команда попадает в затруднительную ситуацию, двойная роль является наиболее вероятной причиной проблемы.
Тестер
Большая часть обязанностей, связанных с тестированием, лежит на плечах программистов, поэтому роль человека, выполняющего тестирование, в команде ХР фокусируется на заказчике. Тестер помогает заказчику в подборе и написании функциональных тестов. Если функциональные тесты не являются частью интеграционного пакета, тестер отвечает за регулярный запуск функциональных тестов и публикацию результатов в обозримом для всех месте.
Тестер ХР – это не отдельный человек, специально нацеленный на разрушение системы и унижение программистов. Однако должен быть кто‑то, кто будет регулярно запускать тесты (если вы не можете запустить тесты модулей и функциональные тесты одновременно), оповещать команду о результатах тестирования и проверять правильность работы тестирующих инструментов.
Глава 23.
Правило 20 на 80
Полная отдача от ХР получается только тогда, когда в силу вступают все методики. Многие практики можно вводить в силу постепенно, однако если все они введены в действие, общий эффект от их использования равен произведению между ними.
Разработчики программного обеспечения привыкли иметь дело с правилом 20 на 80, которое утверждает, что 80% пользы исходит из 20% работы.
Чтобы правило 20 на 80 работало, рассматриваемая система должна обладать элементами управления, в достаточной степени независимыми друг от друга. Например, когда я занимаюсь оптимизацией производительности программы, я могу вносить изменения в несколько разных мест, при этом желательно, чтобы при внесении изменения в одно место это изменение не оказывало бы существенного влияния на все остальные места, в которых я могу повлиять на систему. Я никогда не должен попадать в ситуацию, в которой при изменении одного элемента системы, оказывающего наибольшее влияние на время исполнения программы, я обнаруживаю, что после внесения этого изменения я уже не могу воздействовать на второй по важности элемент системы.
Вард Каннингхэм (Ward Cunningham) рассказывал мне о книге, посвященной освоению техники горнолыжного спуска. Эта книга называлась The Athletic Skier ( Лыжник‑спортсмен). Половина книги была посвящена настройке и подгонке горнолыжных ботинок таким образом, чтобы вы уверенно стояли на лыжах, чувствовали склон и поддерживали равновесие во время спуска. После этого в книге говорилось: Однако после того, как вы выполните 80% всех этих упражнений, вы улучшите вашу ситуацию лишь на 20%. Далее объяснялось, что существует огромная разница между состоянием равновесия и состоянием потери равновесия. Если вы немножко не в равновесии, это может означать, что вы полностью потеряли равновесие. На это влияет огромное количество факторов, например качество настройки ваших горнолыжных ботинок. Если хотя бы один из них настроен неправильно, значит, вы потеряете баланс. По мере того как вы учитываете в своей подготовке все большее количество факторов, ситуация будет очень медленно улучшаться. Однако когда вы внесете в свою подготовку несколько самых последних изменений, вы получите существенные, кардинальные улучшения вашей техники спуска.
Я думаю (и это просто моя гипотеза), что подобное положение вещей имеет место и в отношении ХР. Методики и принципы ХР работают вместе друг с другом, и в результате получается сила, которая действует сильнее, чем сумма составляющих ее частей. Вы не просто выполняете тестирование, вы тестируете систему, которая должна быть простой, и при этом система становится простой благодаря тому, что вы программируете в паре и ваш партнер следит за тем, чтобы вы должным образом перерабатывали код, напоминает вам о том, что вы должны писать больше тестов, и одобрительно хлопает вас по плечу, когда вы избавляетесь от излишней сложности кода, и...
Тут возникает дилемма. Не является ли ХР вещью из разряда все или ничего? Должны ли вы обязательно следовать каждой из входящих в ХР методик или вы рискуете не заметить вообще никаких улучшений? Вовсе нет. Вы можете получить заметное увеличение продуктивности, даже если вы будете использовать только часть методик ХР. Однако я подозреваю, что вы сможете получить гораздо больше, если вы будете по максимуму использовать все методики в комплексе.
Глава 24.
Что делает ХР сложной?
Несмотря на то что отдельные методики без труда могут исполняться обычными программистами в индивидуальном порядке, соединение всех кусков воедино и поддержание их в этом состоянии – далеко не простая задача. Сложной ХР становится в основном из‑за эмоций, в особенности из‑за страха.
Когда люди слушают то, что я им рассказываю об ХР, они говорят: То, о чем ты рассказываешь, кажется таким простым! Да, это действительно очень просто. Не надо обладать ученой степенью в области компьютерных наук для того, чтобы участвовать в ХР‑проекте (в действительности ученая степень частенько является одним из серьезных мешающих факторов).
ХР очень проста в своих деталях, однако ее сложно реализовать на практике.
Повторю это снова. ХР легко понять, но сложно реализовать. Именно так. Методики, составляющие ХР, может изучить каждый, кто занимается программированием. Это несложная часть работы. Сложная часть – это собрать и поддерживать в состоянии баланса. Отдельные составные части ХР поддерживают друг друга, однако существует множество проблем, опасений, страхов, событий и ошибок, которые могут вывести процесс из состояния баланса. Причина, по которой вам приходится жертвовать наиболее технически опытным членом команды, чтобы он исполнял роль инструктора, состоит в том, что задача поддержки процесса в состоянии баланса – это очень непростая задача.
Я не хочу пугать вас. Я не хочу пугать вас больше, чем это необходимо. ХР может с успехом применяться большинством команд, занимающихся разработкой программного обеспечения. (Исключения рассматриваются в следующей главе.) Я хочу рассказать вам о некоторых моментах, показавшихся мне сложными, когда я применял ХР в отношении моего собственного кода, равно как и когда я инструктировал команды, решившие внедрить у себя ХР. Я не хочу нагонять на вас излишний страх, но когда переход к ХР будет для вас сложным (а я вам обещаю, что такие моменты будут), вы должны знать, что вы не одиноки. Сложности у вас возникают потому, что то, чем вы занимаетесь, – это сложно.
Сложно делать вещи простыми. Это звучит неправдоподобно, но иногда проще сделать что‑нибудь более сложное, чем сделать что‑нибудь простое. Это особенно верно, если в прошлом вы долго и успешно делали сложные вещи. Умение видеть мир в самых простых терминах – это очень сложное умение. Проблема состоит в том, что вы должны изменить свою систему ценностей. Вместо того чтобы восхищаться тем, как кто‑то (например, вы) добивается функционирования чего‑либо сложного, вы должны научиться относиться к сложности с презрением и не успокаиваться до тех пор, пока вы не добьетесь тех же самых результатов от более простой системы.
Сложно признавать то, что вы чего‑то не знаете. ХР – это дисциплина, которая основана на предположении, что вы можете работать не быстрее, чем вы можете получать важную информацию, то есть обучаться, поэтому освоение ХР может быть для вас персональным испытанием. А если вы обучаетесь, это означает, что до этого вы чего‑то не знали. Сможете ли вы без каких‑либо опасений и стеснений прийти к заказчику и попросить его объяснить вам то, что для него является простейшей, элементарнейшей концепцией? Сможете ли вы без опасений и стеснений обратиться к вашему партнеру по паре и сказать ему, что существуют некоторые тривиальные, базовые сведения об информационных технологиях, которые вы, откровенно говоря, недостаточно хорошо изучили в школе. Или, может быть, просто забыли.
Сложно взаимодействовать с соратниками. Вся наша система образования ориентирована на индивидуальное продвижение вперед. Если вы работаете над проектом не один, учитель называет это жульничеством, подсказкой и нечестностью и наказывает вас. В большинстве компаний система вознаграждений основана на индивидуальных оценках и повышениях (часто такую систему называют игрой с нулевой суммой), а это тоже стимулирует индивидуальное мышление. В рамках ХР вы должны оттачивать свое мастерство благодаря помощи ваших сотоварищей. Дисциплина ХР основана на тесном взаимодействии всех членов команды. Сложно разрушать эмоциональные стены. Гладкое течение проекта ХР основано на гладком выражении эмоций. Если кто‑либо чувствует себя расстроенным или озлобленным и никому не говорит об этом, через некоторое время это сказывается на производительности команды. Мы привыкли отделять нашу эмоциональную жизнь от нашей деловой жизни, однако команда не может функционировать эффективно, если не будет происходить живого общения, если не будут подчеркиваться страхи, если не будет разряжаться гнев, если счастье не будет делиться между всеми членами команды.
В свое время я пытался разрабатывать программное обеспечение так, как будто у меня нет никаких эмоций, при этом я держался на некотором расстоянии от своих соратников. Это не было эффективным. Когда я говорю другим о том, что чувствую, и слушаю остальных, когда они говорят, что они чувствуют, весь процесс протекает более гладко. Методики ХР настолько далеки от того, о чем мы говорили и о чем мы слышали и с чем мы добивались успеха в прошлом, что вся методика ХР выглядит странно для тех, кто с ней раньше не сталкивался. Наибольшую сложность представляет противоречивость ХР. Когда я встречаюсь с очередным новым менеджером, я часто опасаюсь, что он воспримет то, о чем я говорю, как нечто радикальное, или безумное, или непрактичное. Однако я не знаю другого, лучшего способа разработки программного обеспечения, поэтому со временем я уже научился преодолевать в себе этот страх. Однако когда вы приступаете к объяснению сути ХР незнакомому с этой дисциплиной человеку, вы должны быть готовы к тому, что он отнесется к ХР достаточно жестко.
Небольшие проблемы могут привести к значительным эффектам. Проверки и балансирование ХР достаточно надежны, однако процесс может в некоторой степени варьироваться. При этом необходимо учитывать, что даже на первый взгляд незначительные вещи могут привести к значительным отклонениям. Когда мы работали над системой управления выплатами в команде Chrysler C3, у команды возникли проблемы с реализацией работы к сроку. Мы никак не могли добиться того, чтобы наши предварительные оценки совпадали с реальностью. В каждой очередной итерации мы каждый раз не успевали реализовывать одну или две истории. Для того чтобы определить корень проблемы, мне потребовалось три или четыре месяца. Я услышал, как кто‑то говорит о синдроме первого вторника. Я переспросил, что это означает, и один из членов команды объяснил мне: Синдром первого вторника – это ощущение, которое возникает на следующий день после совещания, посвященного планированию очередной итерации, когда ты приходишь на работу, смотришь на свои истории и не представляешь себе, как можно реализовать все это за то время, которое было оценено как достаточное.
Дело оказалось в следующем. Изначально я описал процесс следующим образом.
1. Распределение заданий между участниками.
2. Оценка заданий участниками в индивидуальном порядке.
3. Перераспределение в случае, если кто‑то оказывается перегруженным.
Однако команда захотела избежать третьего шага, в результате было предложено изменить процесс следующим образом.
1. Коллективная оценка заданий.
2. Распределение заданий между участниками.
Проблема заключалась в том, что связанная с задачей оценка не принадлежала человеку, принимающему на себя ответственность за выполнение этой задачи. Иными словами, получалось, что один человек (или команда в целом) решает, за какое время можно справиться с задачей, а другой человек вынужден работать над решением этой задачи, пытаясь успеть в заданный ему срок. В результате на следующий день исполнитель приходит на работу, смотрит на задачу и с ужасом думает: Разве можно справиться с этим за три дня? Я даже не владею всеми необходимыми для этого знаниями. Согласитесь, что это не самое продуктивное состояние для программиста. Таким образом, на каждую итерацию борьбы с синдромом первого вторника у каждого члена команды уходил день или два. Нет ничего удивительного в том, что они не могли достичь всех поставленных перед ними целей.
Я рассказал эту историю для того, чтобы проиллюстрировать, что небольшие проблемы во время проекта могут стать причиной значительных эффектов. Я не имел в виду, что вы обязаны делать все именно так, как описано в данной книге. Вы можете попробовать сформировать свой собственный процесс разработки. Но именно это и делает ХР сложной – если вы принимаете на себя ответственность за формирование собственного процесса разработки, значит, вы принимаете на себя ответственность за наблюдение за возникновением и решением разного рода проблем.
Управление проектами, основанное на незначительных отклонениях то в одну сторону, то в другую сторону, идет в разрез с традиционными методиками управления, основанными на предварительном планировании с последующим следованием жестко заданному плану. Именно такая дисциплина применяется в большинстве организаций. Финальная сложность, благодаря которой ХР‑проект вполне может умереть, состоит в том, что управление проектом в соответствии с метафорой управления автомобилем совершенно неприемлема в рамках культуры производства, принятой во многих компаниях. Раннее предупреждение о проблемах рассматривается как признак слабости или как жалобы на жизнь. Если ваша компания потребует от вас действовать вопреки принципам, которые вы избрали для себя определяющими, вам потребуется храбрость.
Глава 25.
Когда не следует использовать ХР
Точные пределы использования ХР еще не до конца исследованы. Однако есть известный набор факторов, который делает применение ХР невозможным, – слишком большие команды, недоверчивые заказчики, технология, которая не позволяет легко и просто вносить изменения.
В рамках ХР используются методики, которые сами по себе являются неплохими вне зависимости от того, что вы думаете об общей картине. Вы должны применять их. Точка. Тестирование – хороший пример. Игра в планирование тоже, скорее всего, будет работать, несмотря на то что вы будете большее время тратить на формирование оценок и предварительное проектирование. Однако, как предписывает правило 20 на 80, существует значительная разница между применением всех методик и применением только некоторых из них.
Дисциплину ХР не следует применять абсолютно для любых проектов. При некоторых комбинациях времени, места, команды разработчиков и заказчиков проект ХР может лопнуть, как воздушный шарик. Очень важно не использовать ХР для таких проектов. ХР необходимо использовать там, где эта дисциплина обеспечивает реальные преимущества, и ее не нужно использовать там, где она может дать сбой. Именно этому и посвящена данная книга – прочитав ее, вы сможете решить, когда можно использовать ХР, а когда этого лучше не делать.
Я не буду говорить вам нечто вроде: Не следует использовать ХР для разработки программ управления стратегическими ракетами. Я никогда не разрабатывал программное обеспечение подобного рода, поэтому я не могу сказать вам, на что это похоже. Исходя из этого я не могу сказать вам, будет ли работать ХР в данной ситуации. Однако при этом я так же не могу с уверенностью сказать вам, что в данном случае ХР абсолютно точно не будет работать. Если вы занимаетесь разработкой программ для стратегических ракет, вы должны самостоятельно решить, подходит ли для вас ХР или нет.
Все же я достаточно часто сталкивался с неудачами ХР для того, чтобы рассказать вам о некоторых факторах, благодаря которым ХР совершенно точно не будет работать. Воспринимайте все, о чем я буду рассказывать, как перечень рабочих сред, о которых я точно знаю, что в них ХР работает не самым лучшим образом.
Самым большим барьером, стоящим перед ХР, является культура. Но не национальная культура, которая безусловно тоже немаловажна, а бизнес‑культура. Любой бизнес, который привык вначале разрабатывать план, а затем действовать в строгом соответствии с этим планом, будет сильно конфликтовать с командой, которая намерена постоянно менять план своих действий по мере работы над проектом.
Любой план предусматривает использование емкой, достаточно большой и тщательно продуманной спецификации. Если заказчик или менеджер настаивает на составлении полной спецификации или подробного анализа или разработке полноценного дизайна перед тем, как можно будет сесть за написание кода, тогда возникает сильное трение между культурой команды и культурой заказчика или менеджера. В рамках проекта все же можно будет использовать ХР, однако это будет непросто. Вы предлагаете заказчику или менеджеру способ работы над проектом в форме диалога (игра в планирование), который подразумевает, что они будут находиться в постоянной связи с проектом. Для человека, который и без того очень сильно занят, это может оказаться неприемлемым.
Но однажды я работал для одного банка, представители которого просто очень любили большие куски бумаги. В процессе работы над системой они постоянно настаивали на том, чтобы мы документировали систему. Мы постоянно отвечали им, что если они хотят получить меньше функциональности и больше бумаги, мы будем рады удовлетворить их просьбу. Мы слушали их просьбы о документации в течение нескольких месяцев. По мере того как проект продвигался вперед и становилось ясным, что тесты не только обеспечивают стабильность системы, но и отлично описывают ее поведение, требования о документировании становились все тише и тише. Все же они продолжали настаивать на своем. В самом конце работы над проектом менеджер по разработке сказал нам, что все, что ему нужно, это четырехстраничное обозрение основных объектов системы. Он пришел к выводу, что любой человек, который не в состоянии получить необходимую ему информацию из кода и тестов, вообще не должен трогать код.
Еще одна культура, в рамках которой не следует применять ХР, это культура, в рамках которой вы должны работать внеурочное время для того, чтобы доказать свою преданность компании. Вы не можете работать в стиле ХР, если вы устали. Если объем работы, выполняемый командой, работающей с максимальной скоростью, недостаточен для компании, значит, ХР – это не ваше решение. Если вы работаете над проектом ХР сверхурочно в течение двух недель подряд – это верный признак того, что вы делаете что‑то не так. Вместо того чтобы продолжать работать в напряженном режиме, лучше попытаться обнаружить проблему и устранить ее.
Иногда очень умные программисты с трудом овладевают ХР. Для очень умных людей тяжело поменять их умение делать правильные дальновидные предположения на тесную коммуникацию и постоянную эволюцию системы.
Огромное значение имеет масштаб проекта. Скорее всего, вам не удастся эффективно использовать ХР, если над проектом работает сотня программистов. Пятьдесят программистов – это тоже слишком много. Скорее всего, и двадцать программистов будет много. Десять программистов – это определенно подходящее количество. Если в команде всего три или четыре программиста, вы можете безбоязненно отбросить некоторые из методик, сфокусированных на координации, например игру в планирование итерации. Объем функциональности, который требуется реализовать, и количество людей, которые работают над реализацией этой функциональности, связаны зависимостью, которая ни в коем случае не является линейной.
Если у вас крупномасштабный проект, вы можете экспериментировать с ХР – попробуйте использовать ее в течение месяца с небольшой командой, чтобы проверить, как быстро будет продвигаться разработка. Наиболее узким местом при использовании ХР в крупных проектах является однопоточный интеграционный процесс. Вы должны как‑либо расширить этот процесс, чтобы обеспечить интеграцию нескольких источников кода на одном компьютере.
Вы не можете использовать ХР в случае, если имеете дело с технологией, которая подразумевает экспоненциальный рост затрат, связанных с внесением в систему изменений. Например, если вы имеете дело с мэйнфреймом, планируете использовать установленную на нем реляционную базу данных и не уверены в том, что схема реляционной базы данных в точности соответствует тому, что вам нужно. В подобной ситуации вы не должны использовать ХР. ХР основывается на чистом и простом коде. Если вы усложняете код для того, чтобы избежать модификации 200 существующих приложений, в самом скором времени вы потеряете гибкость, ради которой вы, собственно, и решили использовать ХР.
Еще одним технологическим барьером, препятствующим использованию ХР, является рабочая среда, в которой для обратной связи требуется слишком длительное время. Например, если для компиляции и компоновки вашей системы требуется 24 часа, вы вряд ли сможете интегрировать, собирать и тестировать по несколько раз в день. Если перед тем, как приступить к использованию системы на производстве, вы вынуждены пройти двухмесячную процедуру проверки качества, вы не сможете быстро получать сведения о том, как ведет себя система в условиях реального производства при добавлении или изменении той или иной функциональности.
Я работал в средах, в которых было невозможно тестировать программное обеспечение в обычном смысле этого слова, – в условиях производства система работает на компьютере стоимостью в один миллион долларов, который загружен до предела, и у вас нет еще одного лишнего миллиона долларов. Или существует такое большое количество комбинаций возможных проблем, что вы просто не можете выполнить маломальски осмысленный набор тестов за время, меньшее, чем один день.
В подобной ситуации самым правильным решением будет заменить тестирование длительным предварительным размышлением. Однако в этом случае то, что вы делаете, нельзя будет назвать ХР. Когда я программирую в рабочей среде подобной категории, я не чувствую себя способным свободно видоизменять дизайн системы. Я обязан сформировать необходимую гибкость заранее. В этом случае вы по‑прежнему можете производить качественное программное обеспечение, однако при этом вы не должны использовать ХР.
Помните историю о программистах, офисы которых размещались в разных концах здания? Если вы работаете в неподходящих физических условиях, ХР не будет работать. Как было отмечено, для целей ХР я использовал большую общую комнату с мощными компьютерами в центре и с небольшими отделениями вдоль стен. Однако это только один из возможных вариантов. Вард Каннингхэм (Ward Cunningham) рассказывал мне о проекте WyCach, при работе над которым каждому программисту выделили по отдельному небольшому рабочему месту, отделенному от внешнего мира перегородками из ДСП. Однако каждый такой мини‑офис был достаточно просторным для того, чтобы вместить двух человек. Если два человека хотели работать в паре, они выбирали один из офисов. Если вы абсолютно точно не можете передвигать столы, если уровень шума высок настолько, что сильно мешает разговору, если вы не можете расположиться достаточно близко для того, чтобы обеспечить хорошую коммуникацию, вы не сможете использовать ХР с максимальной эффективностью.
Что не сработает абсолютно точно? Если ваши программисты размещаются на двух этажах, вы можете забыть об ХР. Если программисты расположены на одном этаже, но далеко друг от друга, вы тоже можете забыть об ХР. Если программисты географически удалены друг от друга, то, вы можете попытаться использовать ХР при условии, что над разными логически связанными частями проекта будут работать две команды и что они смогут работать в условиях ограниченной коммуникации между собой. Можно начать работу над проектом при помощи одной команды, выпустить первую версию, затем разделить команду согласно географическим границам, поручить каждой из команд реализацию одной из логически отдельных частей приложения и развивать каждую из частей по отдельности.
Наконец, вы абсолютно точно не сможете работать в стиле ХР, если в одной комнате с вами кричит ребенок. В этом вы мне можете абсолютно точно довериться.
Глава 26.
ХР в работе
ХР может применяться при любой форме контракта, однако разные формы предусматривают использование разных вариаций ХР. В частности, контракты с фиксированной ценой и фиксированным объемом работ благодаря игре в планирование становятся контрактами с фиксированной ценой, фиксированной датой и приблизительно фиксированным объемом работ.
Как ХР вписывается в общераспространенные разновидности бизнес‑практики? Неправильная форма контракта может легко разрушить проект вне зависимости от инструментов, технологии и таланта. В данной главе анализируются некоторые бизнес‑аспекты разработки программного обеспечения, а также то, как вы можете использовать их совместно с ХР.
Заключение
Все методики основаны на страхе. Вы пытаетесь развить у себя привычки, которые помогут вам не допустить, чтобы ваши страхи воплотились в реальность. В этом отношении ХР ничем не отличается от любой другой методики. Разница состоит в том, что страхи запечатлены в ХР.
Методика ХР – это мое детище, и поэтому она отражает мои собственные страхи. Я боюсь:
• делать бессмысленную работу;
• останавливать проекты из‑за того, что я не достиг достаточного технического прогресса;
• делать плохие бизнес‑решения;
• иметь дело с плохими техническими решениями, которые сделаны за меня бизнесменами;
• прийти к концу карьеры разработчика программных систем и понять, что было бы лучше, если бы я больше времени проводил с детьми;
• делать работу, которой я не могу гордиться.
ХР также отражает вещи, которых я не боюсь:
• кодировать;
• изменять мой взгляд на вещи;
• продолжать работу, ничего не зная о будущем;
• надеяться на других людей;
• изменять анализ и дизайн функционирующей системы;
• писать тесты.
Я должен был научиться не бояться этих вещей. Это не пришло ко мне само собой, особенно если учесть, что так много людей говорили мне о том, что именно этих вещей и следует бояться и что я должен прилагать все свои усилия для того, чтобы избежать этих вещей.