Экстремальное программирование. Кент Бек - Экстремальное программирование

Development (разработка, управляемая функциями системы) и др.

По утверждению авторов XP, эта методика представляет собой не столько следование каким-то общим схемам действий, сколько применение комбинации следующих техник. При этом каждая техника важна, и без ее использования разработка считается идущей не по XP, согласно утверждению Кента Бека (Kent Beck) , одного из авторов этого подхода наряду с Уордом Каннингемом (Ward Cunningham) и Роном Джефрисом (Ron Jeffries).

  • Живое планирование (planning game)

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

  • Частая смена версий (small releases)

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

  • Метафора (metaphor) системы

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

  • Простые проектные решения (simple design)

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

  • Разработка на основе тестирования (test-driven development)

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

  • Постоянная переработка (refactoring)

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

  • Программирование парами (pair programming)

    Кодирование выполняется двумя программистами на одном компьютере. Объединение в пары произвольно и меняется от задачи к задаче. Тот, в чьих руках клавиатура, пытается наилучшим способом решить текущую задачу. Второй программист анализирует работу первого и дает советы, обдумывает последствия тех или иных решений, новые тесты, менее прямые, но более гибкие решения.

  • Коллективное владение кодом (collective ownership)

    В любой момент любой член команды может изменить любую часть кода. Никто не должен выделять свою собственную область ответственности, вся команда в целом отвечает за весь код.

  • Постоянная интеграция (continuous integration)

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

  • 40-часовая рабочая неделя

    Сверхурочная работа рассматривается как признак больших проблем в проекте. Не допускается сверхурочная работа 2 недели подряд - это истощает программистов и делает их работу значительно менее продуктивной.

  • Включение заказчика в команду (on-site customer)

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

  • Использование кода как средства коммуникации

    Код рассматривается как важнейшее средство общения внутри команды. Ясность кода - один из основных приоритетов. Следование стандартам кодирования, обеспечивающим такую ясность, обязательно. Такие стандарты, помимо ясности кода, должны обеспечивать минимальность выражений (запрет на дублирование кода и информации) и должны быть приняты всеми членами команды.

  • Открытое рабочее пространство (open workspace)

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

  • Изменение правил по необходимости (just rules)

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

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

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

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

XP как совокупность описанных техник впервые было использовано в ходе работы на проектом C3 (Chrysler Comprehensive Compensation System , разработка системы учета выплат работникам компании Daimler Chrysler). Из 20-ти участников этого проекта 5 (в том числе упомянутые выше 3 основных автора XP) опубликовали еще во время самого проекта и в дальнейшем 3 книги и огромное количество статей, посвященных XP. Этот проект неоднократно упоминается в различных источниках как пример использования этой методики , , . Приведенные ниже данные собраны на основе упомянутых статей , за вычетом не подтверждающихся сведений, и иллюстрируют проблемы некоторых техник XP при их применении в достаточно сложных проектах.

Проект стартовал в январе 1995 года. С марта 1996 года, после включения в него Кента Бека, он проходил с использованием XP. К этому времени он уже вышел за рамки бюджета и планов поэтапной реализации функций. Команда разработчиков была сокращена, и в течение примерно полугода после этого проект развивался довольно успешно. В августе 1998 года появился прототип, который мог обслуживать около 10000 служащих. Первоначально предполагалось, что проект завершится в середине 1999 года и результирующее ПО будет использоваться для управления выплатами 87000 служащим компании. Он был остановлен в феврале 2000 года после 4-х лет работы по XP в связи с полным несоблюдением временных рамок и бюджета. Созданное ПО ни разу не использовалось для работы с данными о более чем 10000 служащих, хотя было показано, что оно справится с данными 30000 работников компании. Человек, игравший роль включенного в команду заказчика в проекте, уволился через несколько месяцев такой работы, не выдержав нагрузки, и так и не получил адекватной замены до конца проекта.

Возможно, это прозвучит странно, но около 75% програмного обеспечения вообще не выходит в люди. С другой стороны, существует множество компаний, которые производят софт в огромном количестве. Все это и многое другое обязывает программистов снижать стоимость разработки. А для этого нужно понимать интересы заказчика, постоянно сотрудничать с ним, чтобы в итоге создать именно то, что ему необходимо.

Методология разработки програмного обеспечения eXtreme Programming (изобретатель - Kent Beck) получает все большее признание благодаря максимальному упрощению процессов проектирования и непосредственной разработки програмных продуктов в среде с быстро изменяющимися требованиями.

Существует всего лишь 5 ценностей экстремального программирования: простота, общение, обратная связь, смелость и уважение ("уважение" добавилось в последней редакции XP). На реализию этих основных ценностей и направлены 12 практических методик XP. Рассмотрим их в небольшом приближении. Кроме изветных многим истин, добавлю свои комментарии по поводу практик, основываясь на своем практическом опыте.

Процесс планирования (planning game). В XP планирование - это основная часть разработки. То, что планы могут внезапно поменяться, учитывается еще в самом начале. Аппетит заказчика приходит во время еды и нужно всегда держать ситуацию под контролем. Общение с заказчиком должно происходить как можно чаще. Это позволит точнее оценить сроки выполнения задач и внести необходимые коррективы в случае необходимости.

Быстрый выпуск версий (small releases). Как бы красиво не был описан продукт, все прелести его использования можно понять только работая с ним. Методика быстрого выпуска версий позволяет понять, чего же хочет заказчик, обеспечивая ранний выпуск рабочих версий продукта.

Комментарий: Как показывает практика, первую раннюю версию можно сделать за 2-8 недель, не зависимо от ожидаемой сложности продукта. Желательно, чтобы первую версию продукта (хотя бы первые несколько итераций) делало 2 человека за одним компьютером. В этом случае очень быстро вырисовывается дизайн системы. Далее можно привлекать еще людей, перераспределив пары.

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

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

Простота реализации (simple design). XP предлагает делать код программы простым. Зачем усложнять себе жизнь, если простую программу легче понимать и поддерживать и она менее подвержена ошибкам.

Опережающее тестирование (test-driven development). Экстремальное программирование рекомендует проверять существующий код как можно чаще. Именно поэтому и практикуется данная методика. Тесты пишутся еще до того, как будет написан кусок кода. Это позволяет лучше понимать поставленные задачи и предоставляет возможность проверить код сразу, как только он будет написан.

Комментарий: У такого подхода есть масса плюсов.

Во-первых, писать тесты перед написанием кода - один из лучших способов гарантировать наличие этих самых тестов.

Во-вторых, исключается нежелание тестировать некоторые "очевидные" ветки выполнения программы, хотя бы потому, что кода еще нет:). Ну и потом, при парном программировании тесты дейтвительно будут лаконичными и качественными.

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

Рефакторинг (design improvement). Добавление новой функциональности и увеличение объема кода усложняет разработку и поиск ошибок. Решением этой проблемы является постоянная переработка (refactoring) кода. Рефакторинг - очень мощная и полезная вещь и заслуживает не то что отдельной статьи, а целых книг.

Комментарий: Не забывайте о ценности "смелость" и не бойтесь поламать систему во время рефакторинга. Тесты покажут, что сломалось и вы быстро исправите ошибки. Даже если тесты не покрывали некоторые аспекты, и вы не заметите какие-то потенциальные проблемы - ничего страшного, все всегда можно исправить. Главное, что дизайн системы стал проще и понятнее, а сложная система - это источник куда более ужасных ошибок, чем ошибки возникшие в результате рефакторинга.

Парное программирование (pair programming). Периодический просмотр чужого кода положительно влияет на его качество. Этот принцип лежит в основе парного программирования. Заключается оно в том, что два программиста одновременно работают за одним компьютером. Как ни странно, затраты на разработку не увеличиваются в два раза, а остаются приблизительно на том же уровне. С другой стороны при парном программировании повышается качество кода, осуществляется неявная и явная передача знаний, а также проиходит постоянное общение между разработчиками.

Совместное владение кодом (collective code ownership). Чаще всего при разработке програмных продуктов за определенную часть кода отвечает один человек. Отпуск, увольнение или же болезнь (прости, Господи) одного из программистов может сильно затормозить разработку продукта. Именно поэтому в XP за один кусок кода отвечает не менее двух человек и любой программист может внести изменения в любую часть програмного кода.

Продолжающаяся интеграция (continuous integration). Команды XP-программистов создают новые билды продукта несколько раз в день. Это позволяет всем программистам быть в курсе происходящего и предотвратить проблемы интеграции с другими продуктами и частями кода.

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

Тем не менее эта практика актуальна до сих пор. Совместное владение кодом никто не отменял: не хочешь тратить время на огромный и сложный merge - потратить время на несколько маленьких мержиков:).

40-часовая неделя (forty hour week). Ради дела люди спопобны на многое, но экстремальное программирование категорически против самопожертвования разработчиков. Человек должен отдыхать, именно тогда он достигнет максимальной производительности в рабочее время.

аверное, каждый проектировщик или аналитик хотя бы раз в жизни сталкивался с заказчиком, стремящимся получить свой проект как можно дешевле и вдобавок в максимально сжатые сроки. Но если стоимость проекта - вполне реальный предмет торга, то вести переговоры о корректировке сроков сдачи проекта куда сложнее. Нетерпеливых клиентов сегодня становится все больше и больше, что объясняется и состоянием современного динамичного рынка, и падающим уровнем доверия между исполнителями и заказчиками, и поведением инвесторов, у которых аппетит приходит во время еды (при наличии более или менее работающей версии продукта деньги на дальнейшую разработку дают намного охотнее), и т.д. В связи с этим классические методологии разработки (при которых долгий цикл собственно проектирования и сбора информации, когда клиент вкладывает значительные средства, а реального результата довольно долго не получает) вступают в весьма жесткое противоречие с интересами нетерпеливого заказчика. Все это и дало толчок развитию альтернативных методологий проектирования в двух основных направлениях: повышение доверия заказчика путем предоставления реальных доказательств успешно развивающегося процесса разработки и резкое сокращение сроков разработки продукта. Группа таких методологий получила название «активное программирование».

Ускоренная и совместная разработка приложений

ак правило, конечные пользователи и представители руководства компании-заказчика полагают, что процесс проектирования не увенчался успехом, если отсутствуют реальные готовые компоненты. Зачастую заказчик настаивает на досрочном проведении этапа реализации проекта, чтобы как можно быстрее получить конкретный результат и продемонстрировать его. В таком случае существует большой соблазн выбрать ускоренную разработку приложений (УРП) или совместную разработку приложений (СРП). Подобные методы предусматривают разработку рабочего прототипа с последующей демонстрацией его пользователям, которые отмечают, что им нравится, а что нет. После этого проектировщик дорабатывает прототип с учетом сделанных замечаний, а затем снова демонстрирует то, что получилось. Процесс повторяется до тех пор, пока пользователи не будут удовлетворены тем, что они видят, а прототип не станет рабочим приложением. Обычно устанавливаются лимит времени и количество итераций, ибо в противном случае пользователи будут бесконечно требовать новых совершенствований прототипа. Теоретически это позволяет получить именно ту систему, которая необходима пользователям.

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

На практике подобный подход к разработке приложений сопряжен с проблемами, перечисленными ниже:

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

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

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

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

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

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

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

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

Возникает вопрос: можно ли решить подобные проблемы и каким образом? Ведь так хочется получить проект максимально быстро! В какой-то мере экстремальное программирование (eXtreme Programming, XP) можно считать эволюцией, а возможно, и революцией в сфере более молодых методологий активного программирования. Подойдет ли данная методология конкретно для вашего коллектива разработчиков - решать вам и только вам, поскольку, например, далеко не все приходят в восторг от экстремальных видов спорта.

Экстремальное программирование

Принципы XP и используемые методы ускорения разработки

Отцом-идеологом экстремального программирования считают Кента Бека (Kent Beck). XP является достаточно молодой методологией, оценки которой весьма противоречивы - от восторженных до резко негативных. Основными принципами являются:

Простота решений (simplicity).

Интенсивная разработка малыми группами (не больше 10 человек), активное общение в группе и между группами (communication).

Обратная связь с клиентом (feedback), который фактически вовлечен в процесс разработки.

Достаточная степень смелости (courage) и желание идти на риск.

Первый фактор ускорения разработки - итеративность: разработка ведется короткими итерациями при наличии активной взаимосвязи с заказчиком. XP - это итеративный процесс разработки, который сам по себе не является революционным. Итерации как таковые предлагается делать короткими, рекомендуемая длительность - 2-3 недели и не более 1 месяца. За одну итерацию группа программистов обязана реализовать несколько свойств системы, каждое из которых описывается в пользовательской истории (user story). Пользовательские истории в данном случае являются начальной информацией, на основании которой создается модуль. Пользовательские истории отличаются от прецедентов (use case): пользовательская история коротка - 1-2 абзаца, тогда как прецеденты обычно пишут достаточно подробными, с основным и альтернативными потоками - таким образом, получается примерно страница плюс схема (наиболее распространенная формализация в настоящее время предложена в UML); истории пользователей пишутся самими пользователями (которые в XP являются частью команды) в отличие от прецедентов, которые обычно пишет системный аналитик. Отсутствие формализации описания входных данных проекта в XP стремятся компенсировать посредством активного включения в процесс разработки заказчика как полноправного члена команды и за счет наличия постоянного контакта с заказчиком (активное общение и непрерывная поддержка обратной связи). В данном случае extreme - это степень привлечения заказчика к программистской кухне, что обусловлено стремлением сжать сроки разработки за счет коммуникации и обратной связи.

Второй фактор ускорения разработки продукта - наличие малых групп и парное программирование (когда два программиста вместе создают код на одном общем рабочем месте). Все это нацелено на достижение высокого уровня общения в группе, а также на как можно более раннее обнаружение проблем (как ошибок, так и срыва сроков). Парное программирование преследует цель стабилизации проекта, так как при данной методологии высок риск потери кода по причине ухода программиста, не выдержавшего интенсивного графика работы. В этом случае второй программист из пары играет роль «наследника» кода (что в классических методиках реализуется в технической документации). Немаловажно и то, как именно распределены группы в рабочем пространстве - в XP используется открытое рабочее пространство, которое предполагает быстрый и свободный доступ всех ко всем; как правило, рабочее пространство строится на основе круга.

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

Практики

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

Планирование процесса (planning game). Вся команда собирается вместе, принимается коллективное решение о том, какие свойства системы будут реализованы в ближайшей итерации. Набор свойств определяется пользовательскими историями. XP-трудоемкость каждого свойства определяется самими программистами.

Тесное взаимодействие с заказчиком (feed-back, on-site customer). Заказчик должен быть членом XP-команды (on-site customer). Он пишет пользовательские истории, выбирает истории, которые будут реализованы в конкретной итерации, и отвечает на вопросы, касающиеся бизнеса. Заказчик должен быть экспертом в автоматизируемой предметной области. Необходимо постоянное наличие обратной связи с заказчиком (feed-back).

Метафора системы (system metaphor). Хорошая метафора системы означает простоту именования классов и переменных. В реальной жизни поиск метафоры - крайне сложное занятие; найти хорошую метафору непросто. В любом случае команда должна иметь единые правила именования.

Простая архитектура (simple design). Любое свойство системы должно быть реализовано как можно проще. Программисты в XP-команде работают под девизом: «Ничего лишнего!». Принимается первое наипростейшее работающее решение, реализуется необходимый уровень функциональности на данный момент. Тем самым экономится время программиста.

Стандарты кодирования (coding conventions). Стандарты кодирования нужны для обеспечения других практик: коллективного владения кодом, парного программирования и рефакторинга. Без единого стандарта выполнять эти практики как минимум сложнее, а в реальности вообще невозможно: группа будет работать в режиме постоянной нехватки времени. Детальные стандарты не требуются, необходимо стандартизировать только важные вещи. Определение наиболее важных объектов стандартизации в XP субъективно.

Рефакторинг (refactoring). Рефакторинг - это оптимизация существующего кода в сторону упрощения, что предусматривает постоянную работу по упрощению кода. Сохраняя код прозрачным и определяя его элементы всего один раз, программисты сокращают число ошибок, которые впоследствии придется устранять. При реализации каждого нового свойства системы программист должен подумать над тем, можно ли упростить существующий код и как это поможет реализовать новое свойство. Кроме того, нельзя совмещать рефакторинг с дизайном: если создается новый код, рефакторинг надо отложить.

Парное программирование (pair programming) - одна из самых известных XP-практик. Все программисты должны работать в парах: один пишет код, другой смотрит. Таким образом, необходимо размещать группу программистов в одном месте, что легче всего сделать на территории заказчика (все необходимые члены команды географически находятся в одном месте); XP наиболее успешно работает в нераспределенных коллективах программистов и пользователей.

40-часовая рабочая неделя. Программист не должен работать более 8 часов в день. Необходимость сверхурочной работы (overtime) - это четкий индикатор проблемы на данном конкретном направлении разработки; к тому же заказчик не платит за сверхурочную работу в XP. Поиск причин сверхурочной работы и их скорейшее устранение - одно из основных правил.

Коллективное владение кодом (collective code ownership). Каждый программист в коллективе XP должен иметь доступ к коду любой части системы и вносить изменения в любой код. Обязательное правило: если программист внес изменения и система после этого работает некорректно, то именно этот программист должен исправить ошибки. В противном случае работа системы уподобится тотальному хаосу.

Частая смена версий (small releases). Минимальная итерация - один день, максимальная - месяц; чем чаще осуществляются релизы, тем больше недостатков системы будет выявлено. Первые релизы помогают выявить недостатки на самых ранних стадиях, далее функциональность системы расширяется (на основании тех же пользовательских историй). Поскольку пользователь включается в процесс разработки начиная с первого релиза, то он оценивает систему и выдает пользовательскую историю плюс feedback. На основании этого определяется следующая итерация: каким будет новый релиз. В XP все направлено на обеспечение непрерывной обратной связи с пользователями.

Непрерывная интеграция (continuous integration). Интеграция новых частей системы должна происходить как можно чаще, как минимум раз в несколько часов. Основное правило интеграции следующее: интеграцию можно производить, если все тесты проходят успешно. Если тесты не проходят, то программист должен либо внести исправления и тогда интегрировать составные части системы, либо вообще не интегрировать их. Правило это жесткое и однозначное - если в созданной части системы имеется хотя бы одна ошибка, то интеграцию производить нельзя. Частая интеграция позволяет быстрее получить готовую систему, вместо того чтобы тратить на сборку неделю.

Тестирование (testing). В отличие от большинства остальных методологий тестирование в XP - одно из важнейших составляющих. Экстремальный подход заключается в том, что тесты пишутся до написания кода. Каждый модуль обязан иметь unit test - тест данного модуля; таким образом, в XP осуществляется regression testing (возвратное тестирование, «неухудшение качества» при добавлении функциональности). Большинство ошибок исправляются на стадии кодирования. Тесты пишут сами программисты; любой программист имеет право написать тест для любого модуля. Еще один важный принцип: тест определяет код, а не наоборот (такой подход носит название test-driven development), то есть кусок кода кладется в хранилище тогда и только тогда, когда все тесты прошли успешно, в противном случае данное изменение кода отвергается.

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

Существующие риски применения методологии

Следует выделить риски XP, способные завалить проект, если не учитывать и не предотвращать их.

Этап планирования (planning game). Программисты реализуют только те функции, которые необходимы для возможностей, выбранных на данной итерации заказчиком. В результате такого решения за кадром остается развитие системы, вследствие чего при разработке возникает необходимость строить «заглушки» и переписывать код.

Постоянное участие заказчика (on-site customer). Представитель заказчика в период работы над системой находится в команде разработчиков, причем требования к квалификации этого человека или команды весьма высоки. Если заказчик не согласился предоставить персонал уровня экспертов, то проект попадает в группу наиболее высокого риска.

Метафора (metaphor). Общий вид системы определяется при помощи метафоры или набора метафор, над которыми совместно работают заказчик и программисты. Если не ведется журнал данного процесса и структура наименований не стандартизована, то такой процесс может оказаться бесконечно итерационным.

Простая архитектура (simple design). В каждый момент времени разрабатываемая система выполняет все тесты и поддерживает все взаимосвязи, определяемые программистом, не имеет дубликатов кода и содержит минимально возможное количество классов и методов. Это правило кратко можно выразить так: «Каждую мысль формулируй один и только один раз». Данный принцип вступает в противоречие с быстротой написания кода. Без наличия высокой самодисциплины и жестких стандартов кода система немедленно попадает в группу риска.

Частая смена версий (small releases). Систему запускают в эксплуатацию уже через несколько месяцев после начала реализации, не дожидаясь окончательного разрешения всех поставленных проблем. Периодичность выпуска новых версий может варьироваться от ежедневной до ежемесячной. Протестировать за такой срок более-менее сложный компонент невозможно; заказчик фактически выступает в роли бета-тестера. Системы, к которым предъявляется требование непрерывной надежной работы (так называемое требование 24Ѕ7), входят в группу риска.

Переработка системы (refactoring). Архитектура системы постоянно эволюционирует. Текущий проект трансформируется, при этом гарантируется правильное выполнение всех тестов. Экстремальное программирование исходит из того, что переделать часть системы всегда можно, причем без особых затрат. Однако практика довольно часто свидетельствует об обратном.

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

Программирование в паре (pair programming). Весь код проекта пишут группы по два человека, использующих одно рабочее место. Человеческий фактор в данном случае играет определяющую роль: пара или работает или нет, третьего не дано.

40-часовая неделя (40-hour weeks). Объем сверхурочных работ не может превышать по длительности одну рабочую неделю. Даже отдельные случаи сверхурочных работ, повторяющиеся слишком часто, служат признаком серьезных проблем, которые требуют безотлагательного решения. Как показывает практика применения экстремального программирования (несмотря на целый ряд положительных примеров, приводимых сторонниками данного метода), сверхурочная работа при таком подходе - это правило, а не исключение, и борьба с проблемами в данном случае - явление постоянное. Усиливается она в период замены текущей сырой версии продукта очередной - менее сырой. Если заказчик не получает постоянных доказательств улучшения системы, значит, у вас возникли серьезные проблемы.

Коллективное владение (collective ownership). Каждый программист имеет возможность при необходимости в любое время усовершенствовать любую часть кода в системе. Без стандарта контроля исходного кода процесс разработки приобретает абсолютно неконтролируемый характер.

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

Тесты (tests). Программисты постоянно пишут тесты для модулей (unit tests). Собранные вместе, эти тесты должны работать корректно. Для этапов итерации заказчики пишут функциональные тесты (functional tests), от которых также требуется правильная работа. Однако на практике это не всегда достижимо. Чтобы принять верное решение, необходимо понять, во что обойдется сдача системы с заранее известным дефектом, и сравнить это с ценой задержки на его устранение. Тесты, написанные самими программистами (особенно в условиях сверхурочных работ), не являются полнофункциональными и уж тем более не учитывают особенностей многопользовательской работы. На более продвинутые тесты у разработчиков обычно не хватает времени. Решается данная проблема путем привлечения на определенный срок контакторов, что связано с большой ролью человеческого фактора: поскольку техническая документация изначально отсутствует, то информация передается посредством общения программистов. Хотя, конечно, можно построить систему разработки таким образом, что от начала до конца всем будут заниматься одни и те же люди. К сказанному необходимо добавить, что тестирование системы вовсе не исчерпывается тестами компонентов (units); не менее важны тесты взаимодействия между ними, это же относится и к тестам надежности работы. И тем не менее метод экстремального программирования не предусматривает создания тестов данного класса. Это объясняется тем, что сами подобные тесты могут представлять достаточно сложный код (особенно это касается тестов - имитаторов реальной работы системы). В данной технологии также никак не учитывается еще один важный класс тестов - тесты поведения системы при росте объемов обрабатываемой информации. При высокой частоте изменения версий выполнить такой тест технологически невозможно, поскольку его проведение требует стабильного и неизменного кода проекта, например в течение недели. В таком случае придется или приостанавливать разработку компонентов, или создавать на время проведения теста параллельную версию проекта, которая будет сохраняться неизменной, тогда как другая при этом будет изменяться. Затем нужно будет выполнить процесс слияния кода. Но в этом случае тест придется создавать заново, так как методы экстремального программирования просто не предусматривают разработку средств, позволяющих прогнозировать поведение системы при тех или иных изменениях. Решать данные проблемы в XP предлагается посредством все того же человеческого фактора и самодисциплины.

Не более чем правила (just rules). Члены коллектива, работающего по технологии экстремального программирования, обязуются выполнять изложенные правила. Однако это не более чем правила, и команда может в любой момент изменить их, если ее члены достигнут принципиального соглашения по поводу внесенных изменений. Данный принцип серьезно зависит от человеческого фактора; нарушение дисциплины разработки влечет за собой срывы сроков и в результате ведет к краху проекта.

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

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

Экстремальное программирование: разработка через тестирование

Посвящается Синди: крыльям моей души

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


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


ISBN 978-0321146533 англ.

ISBN 978-5-496-02570-6


© 2003 by Pearson Education, Inc.

© Перевод на русский язык ООО Издательство «Питер», 2017

© Издание на русском языке, оформление ООО Издательство «Питер», 2017

© Серия «Библиотека программиста», 2017

Предисловие

Чистый код, который работает (clean code that works), – в этой короткой, но содержательной фразе, придуманной Роном Джеффризом (Ron Jeffries), кроется весь смысл методики разработки через тестирование (Test-Driven Development, TDD). Чистый код, который работает, – это цель, к которой стоит стремиться потому, что

Это предсказуемый способ разработки программ. Вы знаете, когда работу можно считать законченной и не беспокоиться о длинной череде ошибок;

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

Улучшает жизнь пользователей ваших программ;

Позволяет вашим коллегам рассчитывать на вас, а вам – рассчитывать на них;

Писать такой код приятнее.

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

Новый код пишется только после того, как будет написан автоматический тест, завершающийся неудачей;

Любое дублирование устраняется.

Два простых правила, не правда ли? Однако они генерируют сложное индивидуальное и групповое поведение со множеством технических последствий:

В процессе проектирования мы постоянно запускаем код и получаем представление о его работе, это помогает принимать правильные решения;

Мы сами пишем тесты, так как не можем ждать, что кто-то другой напишет тесты для нас;

Наша среда разработки должна быстро реагировать на небольшие модификации кода;

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

Два упомянутых правила TDD определяют порядок этапов программирования.

1. Красный – напишите небольшой тест, который не работает, а возможно, даже не компилируется.

2. Зеленый – заставьте тест работать как можно быстрее, при этом не думайте о правильности дизайна и чистоте кода. Напишите ровно столько кода, чтобы тест сработал.

3. Рефакторинг – устраните из написанного кода любое дублирование.

Красный – зеленый – рефакторинг – это мантра TDD.

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

При достаточно низкой плотности дефектов команда контроля качества (Quality Assurance, QA) сможет перейти от реагирования на ошибки к их предупреждению;

С уменьшением количества неприятных сюрпризов менеджеры проекта смогут точнее оценить трудозатраты и вовлечь заказчиков в процесс разработки;

Если темы технических дискуссий будут четко определены, программисты смогут взаимодействовать друг с другом постоянно, а не раз в день или раз в неделю;

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

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

Храбрость

TDD – это способ управления страхом в процессе программирования. Я не имею в виду страх падения со стула или страх перед начальником. Я имею в виду страх перед задачей, «настолько сложной, что я пока понятия не имею, как ее решить». Боль – это когда природа говорит нам: «Стоп!», а страх – это когда природа говорит нам: «Будь осторожен!» Осторожность – это совсем не плохо, однако помимо пользы страх оказывает на нас некоторое негативное влияние:

Страх заставляет нас заблаговременно и тщательно обдумывать, к чему может привести то или иное действие;

Страх заставляет нас меньше общаться;

Страх заставляет нас пугаться отзывов о нашей работе;

Страх делает нас раздражительными.

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

Не пытаться предсказать будущее, а немедленно приступить к практическому изучению проблемы;

Не отгораживаться от остального мира, а повысить уровень коммуникации;

Не избегать откликов, а, напротив, установить надежную обратную связь и с ее помощью тщательно контролировать результаты своих действий;

(с раздражением вы должны справиться самостоятельно).

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

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

Читатели книги Extreme Programming Explaine , должно быть, обратили внимание на разницу в тоне между экстремальным программированием (Extreme Programming, XP) и разработкой через тестирование (Test-Driven Development, TDD). В отличие от XP методика TDD не является абсолютной. XP говорит: «чтобы двигаться дальше, вы обязаны освоить это и это». TDD – менее конкретная методика. TDD предполагает наличие интервала между принятием решения и получением результатов, и предлагает инструменты управления продолжительностью этого интервала. «Что, если в течение недели я буду проектировать алгоритм на бумаге, а затем напишу код, использовав подход “сначала тесты”? Будет ли это соответствовать TDD?» Конечно, будет. Вы знаете величину интервала между принятием решения и оценкой результатов и осознанно контролируете этот интервал.

Большинство людей, освоивших TDD, утверждают, что их практика программирования изменилась к лучшему. Инфицированные тестами (test infected) – такое определение придумал Эрих Гамма (Erich Gamma), чтобы описать данное изменение. Освоив TDD, вы обнаруживаете, что пишете значительно больше тестов, чем раньше, и двигаетесь вперед малюсенькими шагами, которые раньше показались бы вам бессмысленными. С другой стороны, некоторые программисты, познакомившись с TDD, решают вернуться к использованию прежних практик, зарезервировав TDD для особых случаев, когда обычное программирование не приводит к желаемому прогрессу.

Определенно, существуют задачи, которые невозможно (по крайней мере, на текущий момент) решить только при помощи тестов. В частности, TDD не позволяет механически продемонстрировать адекватность разработанного кода с точки зрения безопасности данных и надежности выполнения параллельных операций. Безусловно, безопасность основана на коде, в котором не должно быть дефектов, однако она основана также на участии человека в процедурах защиты данных. Тонкие проблемы параллельного выполнения операций невозможно с уверенностью воспроизвести, просто запустив некоторый код.

аверное, каждый проектировщик или аналитик хотя бы раз в жизни сталкивался с заказчиком, стремящимся получить свой проект как можно дешевле и вдобавок в максимально сжатые сроки. Но если стоимость проекта - вполне реальный предмет торга, то вести переговоры о корректировке сроков сдачи проекта куда сложнее. Нетерпеливых клиентов сегодня становится все больше и больше, что объясняется и состоянием современного динамичного рынка, и падающим уровнем доверия между исполнителями и заказчиками, и поведением инвесторов, у которых аппетит приходит во время еды (при наличии более или менее работающей версии продукта деньги на дальнейшую разработку дают намного охотнее), и т.д. В связи с этим классические методологии разработки (при которых долгий цикл собственно проектирования и сбора информации, когда клиент вкладывает значительные средства, а реального результата довольно долго не получает) вступают в весьма жесткое противоречие с интересами нетерпеливого заказчика. Все это и дало толчок развитию альтернативных методологий проектирования в двух основных направлениях: повышение доверия заказчика путем предоставления реальных доказательств успешно развивающегося процесса разработки и резкое сокращение сроков разработки продукта. Группа таких методологий получила название «активное программирование».

Ускоренная и совместная разработка приложений

ак правило, конечные пользователи и представители руководства компании-заказчика полагают, что процесс проектирования не увенчался успехом, если отсутствуют реальные готовые компоненты. Зачастую заказчик настаивает на досрочном проведении этапа реализации проекта, чтобы как можно быстрее получить конкретный результат и продемонстрировать его. В таком случае существует большой соблазн выбрать ускоренную разработку приложений (УРП) или совместную разработку приложений (СРП). Подобные методы предусматривают разработку рабочего прототипа с последующей демонстрацией его пользователям, которые отмечают, что им нравится, а что нет. После этого проектировщик дорабатывает прототип с учетом сделанных замечаний, а затем снова демонстрирует то, что получилось. Процесс повторяется до тех пор, пока пользователи не будут удовлетворены тем, что они видят, а прототип не станет рабочим приложением. Обычно устанавливаются лимит времени и количество итераций, ибо в противном случае пользователи будут бесконечно требовать новых совершенствований прототипа. Теоретически это позволяет получить именно ту систему, которая необходима пользователям.

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

На практике подобный подход к разработке приложений сопряжен с проблемами, перечисленными ниже:

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

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

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

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

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

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

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

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

Возникает вопрос: можно ли решить подобные проблемы и каким образом? Ведь так хочется получить проект максимально быстро! В какой-то мере экстремальное программирование (eXtreme Programming, XP) можно считать эволюцией, а возможно, и революцией в сфере более молодых методологий активного программирования. Подойдет ли данная методология конкретно для вашего коллектива разработчиков - решать вам и только вам, поскольку, например, далеко не все приходят в восторг от экстремальных видов спорта.

Экстремальное программирование

Принципы XP и используемые методы ускорения разработки

Отцом-идеологом экстремального программирования считают Кента Бека (Kent Beck). XP является достаточно молодой методологией, оценки которой весьма противоречивы - от восторженных до резко негативных. Основными принципами являются:

Простота решений (simplicity).

Интенсивная разработка малыми группами (не больше 10 человек), активное общение в группе и между группами (communication).

Обратная связь с клиентом (feedback), который фактически вовлечен в процесс разработки.

Достаточная степень смелости (courage) и желание идти на риск.

Первый фактор ускорения разработки - итеративность: разработка ведется короткими итерациями при наличии активной взаимосвязи с заказчиком. XP - это итеративный процесс разработки, который сам по себе не является революционным. Итерации как таковые предлагается делать короткими, рекомендуемая длительность - 2-3 недели и не более 1 месяца. За одну итерацию группа программистов обязана реализовать несколько свойств системы, каждое из которых описывается в пользовательской истории (user story). Пользовательские истории в данном случае являются начальной информацией, на основании которой создается модуль. Пользовательские истории отличаются от прецедентов (use case): пользовательская история коротка - 1-2 абзаца, тогда как прецеденты обычно пишут достаточно подробными, с основным и альтернативными потоками - таким образом, получается примерно страница плюс схема (наиболее распространенная формализация в настоящее время предложена в UML); истории пользователей пишутся самими пользователями (которые в XP являются частью команды) в отличие от прецедентов, которые обычно пишет системный аналитик. Отсутствие формализации описания входных данных проекта в XP стремятся компенсировать посредством активного включения в процесс разработки заказчика как полноправного члена команды и за счет наличия постоянного контакта с заказчиком (активное общение и непрерывная поддержка обратной связи). В данном случае extreme - это степень привлечения заказчика к программистской кухне, что обусловлено стремлением сжать сроки разработки за счет коммуникации и обратной связи.

Второй фактор ускорения разработки продукта - наличие малых групп и парное программирование (когда два программиста вместе создают код на одном общем рабочем месте). Все это нацелено на достижение высокого уровня общения в группе, а также на как можно более раннее обнаружение проблем (как ошибок, так и срыва сроков). Парное программирование преследует цель стабилизации проекта, так как при данной методологии высок риск потери кода по причине ухода программиста, не выдержавшего интенсивного графика работы. В этом случае второй программист из пары играет роль «наследника» кода (что в классических методиках реализуется в технической документации). Немаловажно и то, как именно распределены группы в рабочем пространстве - в XP используется открытое рабочее пространство, которое предполагает быстрый и свободный доступ всех ко всем; как правило, рабочее пространство строится на основе круга.

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

Практики

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

Планирование процесса (planning game). Вся команда собирается вместе, принимается коллективное решение о том, какие свойства системы будут реализованы в ближайшей итерации. Набор свойств определяется пользовательскими историями. XP-трудоемкость каждого свойства определяется самими программистами.

Тесное взаимодействие с заказчиком (feed-back, on-site customer). Заказчик должен быть членом XP-команды (on-site customer). Он пишет пользовательские истории, выбирает истории, которые будут реализованы в конкретной итерации, и отвечает на вопросы, касающиеся бизнеса. Заказчик должен быть экспертом в автоматизируемой предметной области. Необходимо постоянное наличие обратной связи с заказчиком (feed-back).

Метафора системы (system metaphor). Хорошая метафора системы означает простоту именования классов и переменных. В реальной жизни поиск метафоры - крайне сложное занятие; найти хорошую метафору непросто. В любом случае команда должна иметь единые правила именования.

Простая архитектура (simple design). Любое свойство системы должно быть реализовано как можно проще. Программисты в XP-команде работают под девизом: «Ничего лишнего!». Принимается первое наипростейшее работающее решение, реализуется необходимый уровень функциональности на данный момент. Тем самым экономится время программиста.

Стандарты кодирования (coding conventions). Стандарты кодирования нужны для обеспечения других практик: коллективного владения кодом, парного программирования и рефакторинга. Без единого стандарта выполнять эти практики как минимум сложнее, а в реальности вообще невозможно: группа будет работать в режиме постоянной нехватки времени. Детальные стандарты не требуются, необходимо стандартизировать только важные вещи. Определение наиболее важных объектов стандартизации в XP субъективно.

Рефакторинг (refactoring). Рефакторинг - это оптимизация существующего кода в сторону упрощения, что предусматривает постоянную работу по упрощению кода. Сохраняя код прозрачным и определяя его элементы всего один раз, программисты сокращают число ошибок, которые впоследствии придется устранять. При реализации каждого нового свойства системы программист должен подумать над тем, можно ли упростить существующий код и как это поможет реализовать новое свойство. Кроме того, нельзя совмещать рефакторинг с дизайном: если создается новый код, рефакторинг надо отложить.

Парное программирование (pair programming) - одна из самых известных XP-практик. Все программисты должны работать в парах: один пишет код, другой смотрит. Таким образом, необходимо размещать группу программистов в одном месте, что легче всего сделать на территории заказчика (все необходимые члены команды географически находятся в одном месте); XP наиболее успешно работает в нераспределенных коллективах программистов и пользователей.

40-часовая рабочая неделя. Программист не должен работать более 8 часов в день. Необходимость сверхурочной работы (overtime) - это четкий индикатор проблемы на данном конкретном направлении разработки; к тому же заказчик не платит за сверхурочную работу в XP. Поиск причин сверхурочной работы и их скорейшее устранение - одно из основных правил.

Коллективное владение кодом (collective code ownership). Каждый программист в коллективе XP должен иметь доступ к коду любой части системы и вносить изменения в любой код. Обязательное правило: если программист внес изменения и система после этого работает некорректно, то именно этот программист должен исправить ошибки. В противном случае работа системы уподобится тотальному хаосу.

Частая смена версий (small releases). Минимальная итерация - один день, максимальная - месяц; чем чаще осуществляются релизы, тем больше недостатков системы будет выявлено. Первые релизы помогают выявить недостатки на самых ранних стадиях, далее функциональность системы расширяется (на основании тех же пользовательских историй). Поскольку пользователь включается в процесс разработки начиная с первого релиза, то он оценивает систему и выдает пользовательскую историю плюс feedback. На основании этого определяется следующая итерация: каким будет новый релиз. В XP все направлено на обеспечение непрерывной обратной связи с пользователями.

Непрерывная интеграция (continuous integration). Интеграция новых частей системы должна происходить как можно чаще, как минимум раз в несколько часов. Основное правило интеграции следующее: интеграцию можно производить, если все тесты проходят успешно. Если тесты не проходят, то программист должен либо внести исправления и тогда интегрировать составные части системы, либо вообще не интегрировать их. Правило это жесткое и однозначное - если в созданной части системы имеется хотя бы одна ошибка, то интеграцию производить нельзя. Частая интеграция позволяет быстрее получить готовую систему, вместо того чтобы тратить на сборку неделю.

Тестирование (testing). В отличие от большинства остальных методологий тестирование в XP - одно из важнейших составляющих. Экстремальный подход заключается в том, что тесты пишутся до написания кода. Каждый модуль обязан иметь unit test - тест данного модуля; таким образом, в XP осуществляется regression testing (возвратное тестирование, «неухудшение качества» при добавлении функциональности). Большинство ошибок исправляются на стадии кодирования. Тесты пишут сами программисты; любой программист имеет право написать тест для любого модуля. Еще один важный принцип: тест определяет код, а не наоборот (такой подход носит название test-driven development), то есть кусок кода кладется в хранилище тогда и только тогда, когда все тесты прошли успешно, в противном случае данное изменение кода отвергается.

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

Существующие риски применения методологии

Следует выделить риски XP, способные завалить проект, если не учитывать и не предотвращать их.

Этап планирования (planning game). Программисты реализуют только те функции, которые необходимы для возможностей, выбранных на данной итерации заказчиком. В результате такого решения за кадром остается развитие системы, вследствие чего при разработке возникает необходимость строить «заглушки» и переписывать код.

Постоянное участие заказчика (on-site customer). Представитель заказчика в период работы над системой находится в команде разработчиков, причем требования к квалификации этого человека или команды весьма высоки. Если заказчик не согласился предоставить персонал уровня экспертов, то проект попадает в группу наиболее высокого риска.

Метафора (metaphor). Общий вид системы определяется при помощи метафоры или набора метафор, над которыми совместно работают заказчик и программисты. Если не ведется журнал данного процесса и структура наименований не стандартизована, то такой процесс может оказаться бесконечно итерационным.

Простая архитектура (simple design). В каждый момент времени разрабатываемая система выполняет все тесты и поддерживает все взаимосвязи, определяемые программистом, не имеет дубликатов кода и содержит минимально возможное количество классов и методов. Это правило кратко можно выразить так: «Каждую мысль формулируй один и только один раз». Данный принцип вступает в противоречие с быстротой написания кода. Без наличия высокой самодисциплины и жестких стандартов кода система немедленно попадает в группу риска.

Частая смена версий (small releases). Систему запускают в эксплуатацию уже через несколько месяцев после начала реализации, не дожидаясь окончательного разрешения всех поставленных проблем. Периодичность выпуска новых версий может варьироваться от ежедневной до ежемесячной. Протестировать за такой срок более-менее сложный компонент невозможно; заказчик фактически выступает в роли бета-тестера. Системы, к которым предъявляется требование непрерывной надежной работы (так называемое требование 24Ѕ7), входят в группу риска.

Переработка системы (refactoring). Архитектура системы постоянно эволюционирует. Текущий проект трансформируется, при этом гарантируется правильное выполнение всех тестов. Экстремальное программирование исходит из того, что переделать часть системы всегда можно, причем без особых затрат. Однако практика довольно часто свидетельствует об обратном.

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

Программирование в паре (pair programming). Весь код проекта пишут группы по два человека, использующих одно рабочее место. Человеческий фактор в данном случае играет определяющую роль: пара или работает или нет, третьего не дано.

40-часовая неделя (40-hour weeks). Объем сверхурочных работ не может превышать по длительности одну рабочую неделю. Даже отдельные случаи сверхурочных работ, повторяющиеся слишком часто, служат признаком серьезных проблем, которые требуют безотлагательного решения. Как показывает практика применения экстремального программирования (несмотря на целый ряд положительных примеров, приводимых сторонниками данного метода), сверхурочная работа при таком подходе - это правило, а не исключение, и борьба с проблемами в данном случае - явление постоянное. Усиливается она в период замены текущей сырой версии продукта очередной - менее сырой. Если заказчик не получает постоянных доказательств улучшения системы, значит, у вас возникли серьезные проблемы.

Коллективное владение (collective ownership). Каждый программист имеет возможность при необходимости в любое время усовершенствовать любую часть кода в системе. Без стандарта контроля исходного кода процесс разработки приобретает абсолютно неконтролируемый характер.

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

Тесты (tests). Программисты постоянно пишут тесты для модулей (unit tests). Собранные вместе, эти тесты должны работать корректно. Для этапов итерации заказчики пишут функциональные тесты (functional tests), от которых также требуется правильная работа. Однако на практике это не всегда достижимо. Чтобы принять верное решение, необходимо понять, во что обойдется сдача системы с заранее известным дефектом, и сравнить это с ценой задержки на его устранение. Тесты, написанные самими программистами (особенно в условиях сверхурочных работ), не являются полнофункциональными и уж тем более не учитывают особенностей многопользовательской работы. На более продвинутые тесты у разработчиков обычно не хватает времени. Решается данная проблема путем привлечения на определенный срок контакторов, что связано с большой ролью человеческого фактора: поскольку техническая документация изначально отсутствует, то информация передается посредством общения программистов. Хотя, конечно, можно построить систему разработки таким образом, что от начала до конца всем будут заниматься одни и те же люди. К сказанному необходимо добавить, что тестирование системы вовсе не исчерпывается тестами компонентов (units); не менее важны тесты взаимодействия между ними, это же относится и к тестам надежности работы. И тем не менее метод экстремального программирования не предусматривает создания тестов данного класса. Это объясняется тем, что сами подобные тесты могут представлять достаточно сложный код (особенно это касается тестов - имитаторов реальной работы системы). В данной технологии также никак не учитывается еще один важный класс тестов - тесты поведения системы при росте объемов обрабатываемой информации. При высокой частоте изменения версий выполнить такой тест технологически невозможно, поскольку его проведение требует стабильного и неизменного кода проекта, например в течение недели. В таком случае придется или приостанавливать разработку компонентов, или создавать на время проведения теста параллельную версию проекта, которая будет сохраняться неизменной, тогда как другая при этом будет изменяться. Затем нужно будет выполнить процесс слияния кода. Но в этом случае тест придется создавать заново, так как методы экстремального программирования просто не предусматривают разработку средств, позволяющих прогнозировать поведение системы при тех или иных изменениях. Решать данные проблемы в XP предлагается посредством все того же человеческого фактора и самодисциплины.

Не более чем правила (just rules). Члены коллектива, работающего по технологии экстремального программирования, обязуются выполнять изложенные правила. Однако это не более чем правила, и команда может в любой момент изменить их, если ее члены достигнут принципиального соглашения по поводу внесенных изменений. Данный принцип серьезно зависит от человеческого фактора; нарушение дисциплины разработки влечет за собой срывы сроков и в результате ведет к краху проекта.

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

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