Кент Бек - Экстремальное программирование. Разработка через тестирование. Благодаря использованию чрезвычайно коротких циклов разработки ХР предлагает быструю, реальную и постоянно функционирующую обратную связь. Что такое ХР

И другие.

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

Энциклопедичный YouTube

    1 / 5

    Экстремальное программирование (XP) - основные приемы

    Hexlet Webinar #6: экстремальное программирование

    Life Tips. Зачем участвовать в соревнованиях по программированию?

    032. Парное программирование - Сергей Бережной

    Канал экстремального программирования v. 2.0

    Субтитры

Основные приёмы XP

Двенадцать основных приёмов экстремального программирования (по первому изданию книги Extreme programming explained ) могут быть объединены в четыре группы:

  • Короткий цикл обратной связи (Fine-scale feedback)
    • Разработка через тестирование (Test-driven development)
    • Игра в планирование (Planning game)
    • Заказчик всегда рядом (Whole team, Onsite customer)
    • Парное программирование (Pair programming)
  • Непрерывный, а не пакетный процесс
    • Непрерывная интеграция (Continuous integration)
    • Рефакторинг (Design improvement, Refactoring)
    • Частые небольшие релизы (Small releases)
  • Понимание, разделяемое всеми
    • Простота (Simple design)
    • Метафора системы
    • Коллективное владение кодом (Collective code ownership) или выбранными шаблонами проектирования (Collective patterns ownership)
    • Стандарт кодирования (Coding standard or Coding conventions)
  • Социальная защищённость программиста (Programmer welfare):
    • 40-часовая рабочая неделя (Sustainable pace, Forty-hour week)

Тестирование

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

  • юнит-тестирование модулей;

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

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

Для XP более приоритетным является подход, называемый TDD (от англ. test-driven development - разработка через тестирование). В соответствии с этим подходом сначала пишется тест, который изначально не проходит (так как логики, которую он должен проверять, ещё просто не существует), затем реализуется логика, необходимая для того, чтобы тест прошёл. TDD, в некотором смысле, позволяет писать код, более удобный в использовании - потому что при написании теста, когда логики ещё нет, проще всего позаботиться об удобстве будущей системы.

Игра в планирование

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

Заказчик всегда рядом

«Заказчик» в XP - это не тот, кто оплачивает счета, а конечный пользователь программного продукта. XP утверждает, что заказчик должен быть всё время на связи и доступен для вопросов.

Парное программирование

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

Непрерывная интеграция

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

Рефакторинг

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

Частые небольшие релизы

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

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

Простота проектирования

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

Метафора системы

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

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

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

Стандарты кодирования

Все члены команды в ходе работы должны соблюдать требования общих стандартов кодирования. Благодаря этому:

  • члены команды не тратят время на споры о вещах, которые фактически никак не влияют на скорость работы над проектом;
  • обеспечивается эффективное выполнение остальных практик.

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

Коллективное владение

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

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

Вначале была модель «водопада» (рис.1а): мы просим пользователей однозначно сформулировать свои требования; мы разрабатываем проект системы, которая сделает все, что хотят пользователи; мы пишем код; мы тестируем программу, дабы убедиться, что она действительно делает то, что требуется. Все получается замечательно.

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

Итак, длинный цикл разработки плох, поскольку не способен приспосабливаться к изменениям. Тогда, возможно, надо сократить цикл, и все проблемы будут решены? На рис. 1b дана иллюстрация перерождения модели «водопада» в итеративную модель.

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

Академическое сообщество разработчиков ПО взялось разрешить проблему высокой стоимости изменений и создало новые технологии - реляционные базы данных, модульное программирование, сокрытие информации. Но что если все эти труды уже исчерпали свой потенциал? И нам удастся найти новый способ снизить расходы на внесение изменений, не разрезая «водопад» на части, а просто смешав все его компоненты? То, что получилось в результате, показано на рисунке 1с. Мы назвали это «экстремальным программированием» (Extreme Programming, XP).

Анатомия XP

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

Цикл разработки XP

На рис. 2 процесс XP соотносится с различными осями времени, где в качестве единицы измерения используются годы, месяцы, недели и дни. Заказчик определяет очередную версию (release) системы, выбирая наиболее ценные функции (в XP их называют историями - story) из всех возможных. Ценность функций определяется материальными и временными затратами на их реализацию командой разработчиков.

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

Истории

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

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

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

Версия

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

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

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

Итерация

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

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

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

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

Задача

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

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

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

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

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

Тест

Если говорить о ключевом методе ХР, то это, безусловно, тестирование модулей (unit testing). Как вы уже могли понять, тестирование модулей является неотъемлемой частью повседневной работы каждого программиста. Две особенности делают процесс тестирования в ХР гораздо эффективным по сравнению с традиционными методами: программисты сами пишут свои тесты и делают это до начала кодирования. Конечно, если подходить к программированию как к постепенному изучению проблемы, а изучение проблемы считать наиболее эффективным средством обратной связи с заказчиком, то больше всего пользы вам принесут тесты, написанные третьим лицом через несколько дней или недель после завершения кодирования. ХР учитывает общепринятое мнение, что программисты не могут правильно протестировать свой собственный код, поэтому и обязывает их работать парами.

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

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

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

У Вас проблемы?

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

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

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

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

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

Текучесть кадров. Предположим, один из членов команды решил ее покинуть. Не окажетесь ли вы в тупиковой ситуации из-за отсутствия нужных документов ли отчетов? Прежде всего, заметим, что некоторая текучесть кадров полезна для команды разработчиков и отдельных ее членов. Хотелось бы, конечно, чтобы, уходя, люди руководствовались положительными мотивами. Если, отправляясь домой в конце очередной недели, программист видит конкретные положительные результаты своей деятельности, вероятность его разочарования в работе и возникновения желания уйти значительно снижается.

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

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

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

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

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

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

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

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

Строгое разграничение между деловыми и техническими решениями, которое проводит ХР, восходит к работам архитектора Кристофера Александра. В его книге «The Timeless Way of Building» отмечается, что те, кто эксплуатирует здание, должны быть допущены к принятию важных решений в процессе его сооружения.

Принятые в ХР принципы быстрого развития плана в соответствии с вносимыми техническими и связанными с бизнесом изменениями, отражают принципы методологии Scrum и разработанного Уордом Кэнингхемом языка шаблонов Episodes .

Идея специфицирования и планирования проекта с точки зрения реализуемых возможностей восходит к работам Ивара Якобсона .

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

«Спиральная модель» (Spiral Model) Барри Боэма была первой реакцией на устаревание модели водопада. Долгое время в освоении мощных технологий никто не мог превзойти Дейва Томаса и его коллег из Object Technology International, создавших метод JIT .

Корни принципа метафор, которые используются в ХР, можно найти в книгах Джорджа Лакоффа и Марка Джонсона, в частности, в их последней работе «Philoslphy in the Flesh» . Этот принцип предложен также Ричардом Койне, который связывал метафору и разработку программного обеспечения с точки зрения постмодернистской философии .

Наконец, то значительное внимание, которое ХР уделяет организации офисного пространства, проистекает из работ Джима Коплиена , Тома ДеМарко и Тима Листера , отмечавших влияние окружающих условий на работу программистов.

Примеры выполнения проектов с использованием XP

Компания Acxiom: на пути к достижению общей цели

Джи Ханнула

Команда: менеджеры, бизнес-аналитики, разработчики, тестировщики, технические писатели

Приложение: база данных управления кампанией

Срок реализации: 3 года

В компании Acxiom на основе склада данных создали приложение управления бизнесом, использовав для этого инструментарий распределенной объектно-ориентированной разработки Forte. Небольшая команда разработчиков - всего 10 человек - при создании приложения твердо придерживалась принципов объектно-ориентированного программирования и коллективной разработки. Из трех лет, затраченных на разработку, в течение двух последних команда, включавшая в себя менеджеров, бизнес-аналитиков, разработчиков, тестировщиков и технических писателей, использовала методы экстремального программирования и именно благодаря этому достигла успеха.

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

Много сил пришлось потратить на тестирование модулей, поскольку Forte не предлагает встроенных базовых средств для тестирования. Нам пришлось создать свои и с их помощью успешно провести тестирование. Недавно мы перешли на язык программирования Java и теперь как средство тестирования используем JUnit.

Когда мы только начинали работать по принципам ХР, среди нас нашлись программисты, не пожелавшие использовать его методы. Они считали, что эти методы не соответствуют выработанному ими стилю программирования и помешают им работать продуктивно. В результате больше всего проблем возникало с компонентами системы, написанными этими людьми. Эти разработчики игнорировали работу в паре, и по своим умениям стали уступать другим членам команды, которые воспользовались представленным им шансом поучиться друг у друга. Два опытных программиста, которые работают в тесной взаимосвязи друг с другом и остальной частью команды, всегда будут превосходить по мастерству «индивидуала», будь он даже семи пядей во лбу.

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

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

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

DaimlerChrysler: лучшая в мире команда

Чет Хендриксен

Команда: 15 человек, из них 10 программистов

Приложение: полномасштабная автоматизация расчета платежных ведомостей

Срок реализации: 4 года

Работа над проектом С3 была начата в январе 1995 года. Корпорация Chrysler заключила контракт с партнерской компанией, в соответствии с которым за реализацию проекта бралась объединенная команда разработчиков из обеих организаций. Наши партнеры придерживались методологии разработки, ориентированной на использование графического интерфейса и игнорировавшей автоматизацию тестирования. В результате мы получили систему, которая изобиловала невыразительной графикой и для большинства служащих вычисляла зарплату неправильно. Для создания месячной платежной ведомости такой системе понадобилось бы около 100 дней. Мы поняли, что написанная нами программа никогда не будет реально использоваться.

Мы обратились к Кенту Беку с просьбой помочь отрегулировать производительность системы. Он обнаружил у нас те же явления, с которыми сам постоянно сталкивается, берясь за задачу настройки производительности: плохо продуманный код, тесты, которые нельзя запустить повторно, руководство, потерявшее уверенность в своем проекте. Кент Бек порекомендовал выбросить весь написанный код и начать полномасштабный ХР-проект.

Прежний контракт был разорван, и Chrysler почти наполовину обновила свою команду разработчиков. Начиная с этого момента мы действовали по правилам ХР. Были распределены обязанности, спланированы итерации, установлены правила тестирования, опробовано и принято в качестве стандарта программирование в паре. К концу 33-й недели мы получили систему, в которой уже можно было начинать отлаживать производительность и проводить параллельное тестирование. Мы могли приступить к настройке производительности, поскольку система была хорошо продумана и подкреплена полным набором модульных тестов. Мы были готовы к параллельному тестированию, поскольку серия функциональных тестов наглядно продемонстрировала заказчику наличие в системе требуемых возможностей.

Этот этап реализации С3 был запущен в мае 1997 года, хотя мы рассчитывали на более ранние сроки. Срыв наших планов был обусловлен двумя факторами. Во-первых, мы решили заменить только внутренние компоненты платежной системы. Все внешние интерфейсы остались нетронутыми. Поставить в соответствие выходные данные новой системы компонентам старой оказалось гораздо более сложной задачей, чем мы предполагали. Во-вторых, мы решили в течение любого платежного периода не инициировать реализацию специальных требований, таких, например, как обработка W-2, участие в прибыли или общее повышение заработной платы. В результате то, что должно было быть сделано в ноябре, перенеслось на апрель.

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

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

Ford Motor: уникальное сочетание оперативности и качества

Дон Уэлс

Команда: 17 человек, из них 12 программистов

Приложение: система анализа затрат

Срок реализации: 6 лет

Отдел финансовых систем компании Ford Motor разрабатывает аналитическую систему Vehicle Costing and Profit System (VCAPS), которая создает отчеты по доходам от производства, расходам, чистому доходу и прибыли. Входными данными для системы являются инженерные спецификации продукции, фиксированные затраты и расходы и переменные затраты, например, рабочие часы. VCAPS аккумулирует все эти данные и подготавливает подробные отчеты с анализом затрат, которые обеспечивают эффективное прогнозирование и принятие корпоративных решений. Работа над проектом VCAPS была начата в 1993 году. При разработке использовались VisualWorks и GemStone Smalltalk. В данный момент поддержкой системы VCAPS занимается небольшая группа специалистов, и в скором времени она будет заменена более современным приложением.

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

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

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

Дальше мы сделали несколько модульных тестов и уже через год 40% системы было протестировано, а руководство отметило сокращение числа сообщений об ошибках на 40%. После этого на ХР обратили пристальное внимание.

Мы решали проблемы, реализуя все новые методы ХР. Тесты позволили нам перейти к непрерывной интеграции и частой смене версий. Это, в свою очередь, открыло дорогу к коллективному владению и переработке системы. Мы стремились создавать простой проект. Наконец наступил момент, когда мы решили попробовать программировать в парах. И нам пришлось немало потрудиться, чтобы добиться в этом успеха. Поначалу нашим разработчикам этот метод показался чрезвычайно неудобным; потребовалось время, чтобы привыкнуть и почувствовать себя в нем достаточно комфортно.

Через полтора года количество системных сбоев снизилось настолько, что наши заказчики и руководство смогли констатировать значительно более высокую стабильность системы. Для нас это символизировало успех принципов ХР.

Tariff System: тесты, которые можно читать

Роб Ми

Команда: три разработчика

Приложение: система вычисления тарифов на перевозки

Срок реализации: 3 месяца

Tariff System - часть большого проекта, реализованного с помощью SmallTalk/GemStone в одной из крупных международных компаний, специализирующихся на контейнерных перевозках. Подход ХР позволил за три месяца силами трех человек пройти все этапы разработки этой подсистемы, от замысла до ввода в эксплуатацию. Результат оказался замечательно стабильным и простым в сопровождении.

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

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

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

Embracing Change with Extreme Programming, Kent Beck. Computer, October, 1999, pp. 70-77, Reprinted with permission, Copyright IEEE, 1999, All rights reserved.

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 работников компании. Человек, игравший роль включенного в команду заказчика в проекте, уволился через несколько месяцев такой работы, не выдержав нагрузки, и так и не получил адекватной замены до конца проекта.

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

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

Права на издание получены по соглашению с 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 не позволяет механически продемонстрировать адекватность разработанного кода с точки зрения безопасности данных и надежности выполнения параллельных операций. Безусловно, безопасность основана на коде, в котором не должно быть дефектов, однако она основана также на участии человека в процедурах защиты данных. Тонкие проблемы параллельного выполнения операций невозможно с уверенностью воспроизвести, просто запустив некоторый код.

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

Права и роли

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

Заказчик

Человек или группа людей, заинтерисованных в создании конкретного программного продукта. Он имеет следуещие права и обязанности:

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

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

Разработчик

Один или группа от двух до десяти человек, занимающихся непосредственно программированием и сопутствующими инженерными вопросами. Разработчик наделён следующими правами и обязанностями:

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

Роли внутри роли

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

Сторона заказчика

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

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

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

Сторона разработчика

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

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

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

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

Внешние роли

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

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

Соглашение о кодировании

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

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

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

Коллективное владение кодом

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

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

CRC Сессия

Используйте Class, Responsibilities, Collaboration (CRC - Класс, Обязанности, Взаимодействие) карточки для дизайна системы командой. Использование карточек позволяет легче приучиться мыслить обьектами а не функциями и процедурами. Также карточки позволяют большему количеству людей участвовать в процессе дизайна (в идеале - всей команде), а чем больше людей делает дизайн, тем больше интересных идей будет привнесено.

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

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

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

Заказчик

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

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

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

Выбирайте самое простое решение

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

Рефакторите чужой код если он кажется вам сложным. Если что-то выглядит сложным - это верный признак проблемы в коде.

Сохраняйте решения насколько возможно простыми как можно дольше. Никогда не добавляйте функциональность на будущее - до того как появляется в ней необходимость. Однако имейте в виду: сохранять дизайн простым - тяжелая работа.

Функциональные тесты

Приемочные тесты (ранее их также называли Функциональные) пишутся на основе User Story . Они рассматривают систему как черный ящик. Заказчик ответственен за проверку корректности функциональных тестов. Эти тесты используются для проверки работоспособности системы перед выпуском ее в производство. Функциональные тесты автоматизируются так, чтобы имелась возможность их часто запускать. Результат сообщается команде и команда отвечает за планирование исправлений функциональных тестов.

Частая интеграция

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

Каждая пара разработчиков должна отдавать свой код как только для этого появляется разумная возможность. Это может быть когда все UnitTest-ы проходят на 100%. Отдавая изменения несколько раз в день, Вы сводите проблемы интеграции практически к нулю. Интеграция - это деятельность вида "заплати сейчас или заплати больше позднее". Поэтому интегрируя изменения ежедневно маленькими порциями вы не окажетесь перед необходимостью тратить неделю чтобы связать систему в одно целое непосредственно перед сдачей проекта. Всегда работайте над последней версией системы.

Для менеджера. Если разработчик не отдает изменений дольше одного дня - это ясный индикатор серьезной проблемы. Вы должны немедленно разобраться в чем дело. Весь опыт XP команд говорит что всегда причиной задержки является плохой дизайн и его всегда потом приходится переделывать.

Планирование Итерации

Iteration Planning Meeting созывается перед началом каждой итерации для планирования задач которые будут сделаны в этой итерации. Для итерации выбираются User Stories, которые выбрал заказчик в плане релиза начиная с самых важных для заказчика и самых плохих (сопряженных с риском) для разработчиков. Также в итерацию включаются неработающие Функциональные тесты.

User Stories и невыполненные Функциональные тесты разбиваются на задачи. Задачи записываются на карточках. Эти карточки и есть детальный план на итерацию. Каждая задача должна быть продолжительностью от 1 до 3 идеальных дней.

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

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

Откладывание User Story на следующую итерацию может выглядеть страшно, но не позволяйте себе жертвовать рефакторингом и Unit Test-ами чтобы сделать больше. Задолженность по этим категориям быстро замедлит вашу скорость. Не делайте того, что по-вашему понадобится в следующих итерациях - делайте только то что необходимо для выполнения текущих User Stories.

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

Итерации

Итеративная разработка увеличивает гибкость процесса. Разделите ваш план на итерации продолжительностью от 2 до 3 недель. Сохраняйте постоянную продолжительность итерации на время проекта. Пусть итерации будут пульсом вашего проекта. Это тот ритм который позволит сделать измерение прогресса и планирование простым и надежным.

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

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

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

Меняйтесь задачами

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

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

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

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

Такая практика также стимулирует появление новых идей и улучшение кода.

Оставляйте оптимизацию на потом

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

Сделайте чтобы это работало, затем чтобы работало правильно, затем чтобы работало быстро.

Парное программирование

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

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

Безжалостно Рефакторить!

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

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

План Релиза

План Релиза разрабатывается на собрании по планированию Релиза. Релиз Планы описывают взгляд на весь проект и используются в дальнейшем для планирования итераций.

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

Сущность собрания по планированию релиза для команды разработчиков в том, чтобы оценить каждую User Story в идеальных неделях. Идеальная неделя - это сколько по-вашему займет время выполнение задачи если ничто больше вас не будет отвлекать. Ни зависимостей, ни дополнительных задач, но включая тесты. Заказчик затем решает какие задачи наиболее важны или имеют более высокий приоритет.

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

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

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

Частые Релизы

Разработчики должны выпускать версии системы пользователям (или бета-тестерам) как можно чаще.

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

Пробное решение

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

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

Собрание стоя

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

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

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

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

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

Метафора Системы

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

Unit Test-ы

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

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

Unit тест для класса хранится в общем репозитории вместе с кодом класса. Никакой код не может быть выпущен без Unit теста. Перед отдачей кода разработчик должен удостовериться что все тесты проходят без ошибок. Никто не может отдать код, если все не прошли 100%. Другими словами поскольку до ваших изменений все тесты проходили, то если вы имеете ошибки, то это результат ваших изменений. Вам и исправлять. Иногда бывает неправильным или неполным код теста. В таком случае надо исправлять его.

Огромным искушением является сэкономить на Unit тестах когда мало времени. Но этим Вы только обманываете себя. Чем сложнее написать тест, тем больше времени он потом сэкономит. Это доказано практикой.

Unit тесты позволяют осуществить коллективное владение кодом. Они позволяют относительно легко пересматривать плохой код. Также Unit тесты позволяют в любой момент иметь стабильно работающую систему.

User Story

User Story (что-то типа рассказа пользователя) - это описание того как система должна работать. Каждая User Story написана на карточке и представляет какой-то кусок функциональности системы, имеющий логический смысл с точки зрения Заказчика. Форма - один-два абзаца текста понятного пользователю (не сильно технического).

User Story пишется Заказчиком. Они похожи на сценарии использования системы, но не ограничиваются пользовательским интерфейсом. По каждой истории пишутся функциональные тесты, подтверждающие что данная история корректно реализована - их еще называют приемочными (Acceptance tests).

Каждой User Story дается приоритет со стороны бизнеса (пользователь, заказчик, отдел маркетинга) и оценка времени выполнения со стороны разработчиков. Каждая история разбивается на задачи и ей назначается время когда ее начнут реализовывать.

User Stories используются в XP вместо традиционных требований. Главное отличие User Story от требований (requirements) - уровень детализации. User Story содержит минимум информации, необходимой для обоснованной оценки того, сколько времени надо на ее реализацию.

Типичная User Story занимает 1-3 недели идеального времени. История требующая менее 1 недели слишком детализирована. История требующая более 3 недель может быть разбита на части - отдельные истории.

Скорость проекта

Скорость Проекта (или просто скорость) это мера того, как быстро выполняется работа в вашем проекте.

Чтобы измерить скорость проекта, вы просто должны посчитать обьем User Stories, или как много (по времени) задач было выполнено за итерацию. Просто посчитайте суммарное время оценки обьема работы (идеальное время).

Во время планирования релиза скорость проекта используется для оценки того сколько User Stories может быть сделано.

Во время планирования итерации, скорость проекта в предыдущей итерации используется для определения того сколько User Stories надо планировать в текущую итерацию.

Этот простой механизм позволяет разработчикам восстановиться после трудной итерации. Если у вас после восстановления остается свободное время - идете к заказчику и просите еще User Story. В результате скорость опять возрастет.

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

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

Когда обнаружена ошибка

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

Невыполнившийся функциональный тест требует создания Unit Test . Это помогает сфокусировать усилия по отладке и четко показывает когда ошибка исправлена.

Вам это не понадобится

Воздержитесь от заполнения системы вещами, которые понадобятся вам в будущем. Только 10% от ожидаемого действительно понадобится вам в первоначальном виде, то есть 90% вашего времени будет потрачено впустую.

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