Введение

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

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

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

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

Основной процесс планирования в экстремальном программировании называется Игра планирования. Игра – это встреча, которая проходит один раз в итерацию, как правило, раз в неделю. Процесс планирования делится на две части:

Планирование выпуска: Этот процесс сосредоточен на определении того, какие требования будут включены в ближайшие релизы и когда они должны быть реализованы. В нём участвуют как заказчики, так и разработчики. Планирование выпуска состоит из трёх фаз:
Фаза исследования: На этой фазе заказчик предоставляет краткий список высокоприоритетных требований к системе. Эти требования записываются на карточки пользовательских историй. Фаза обязательств: На этой фазе бизнес-заказчик и разработчики берут на себя обязательства по функциональности, которая будет включена, и дате следующего релиза. Фаза корректировки: На этой фазе план может быть скорректирован, добавлены новые требования и/или изменены или удалены существующие. Планирование итерации: Этот процесс планирует действия и задачи разработчиков. Заказчик в нём не участвует. Планирование итерации также состоит из трёх фаз:
Фаза исследования: На этой фазе требования преобразуются в конкретные задачи. Задачи записываются на карточки задач. Фаза обязательств: Задачи назначаются программистам, и оценивается время, необходимое для их выполнения. Фаза корректировки: Задачи выполняются, а конечный результат сопоставляется с исходной пользовательской историей. Цель Игры планирования – направить разработку продукта к поставке. Вместо того, чтобы пытаться точно предсказать даты, когда будут нужны и готовы результаты (что сложно сделать), она направлена на "управление проектом" к поставке с помощью простого подхода. Подход Игры планирования используется не только в разработке программных систем, но и в других областях. Например, его используют команды в контексте бизнес-гибкости.

Этап разведки

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

Фаза обязательств

Этот этап включает определение затрат, выгод и влияния на сроки. Он состоит из четырех компонентов:

Сортировка по ценности: Бизнес-подразделение сортирует пользовательские истории по бизнес-ценности. Сортировка по риску: Разработка сортирует истории по уровню риска. Определение скорости: Разработка определяет свою производительность. Выбор объема: Определяются пользовательские истории, которые будут завершены в следующем релизе. На основе выбранных пользовательских историй определяется дата релиза.

Сортировка по стоимости

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

Фаза рулевого управления

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

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

При планировании учитывается скорость команды, измеряемая в story points. Продолжительность итерации может составлять от 1 до 3 недель.

Этап разведки

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

Фаза обязательств

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

Разработка на основе испытаний

Единичные тесты — это автоматизированные тесты, которые проверяют функциональность отдельных частей кода (например, классов, методов). В рамках XP, единичные тесты пишутся до написания самого кода. Этот подход призван стимулировать программиста к обдумыванию условий, при которых его код может работать некорректно. XP утверждает, что программист завершил работу над определенным фрагментом кода, когда он не может придумать больше условий, при которых этот код может дать сбой. Разработка через тестирование (TDD) осуществляется путем быстрого последовательного выполнения следующих шагов, каждый из которых занимает не более нескольких минут, а желательно – значительно меньше. Поскольку для реализации одной пользовательской истории обычно требуется от одного до двух дней работы, для каждой истории потребуется большое количество таких циклов. Написать единичный тест: Программисты пишут минимальный тест, который должен завершиться неудачей, поскольку функциональность еще не полностью реализована в производственном коде. Убедиться, что тест завершился неудачей: Программисты проверяют, что тест действительно завершился неудачей. Хотя это может показаться пустой тратой времени, этот шаг критически важен, поскольку он подтверждает правильность вашего представления о состоянии производственного кода. Если тест не завершается неудачей, программисты должны определить, есть ли ошибка в тестовом коде, или же производственный код уже поддерживает функциональность, описанную в новом тесте. Написать код: Программисты пишут минимально необходимое количество производственного кода, чтобы новый тест прошел. Запустить тест: Единичные тесты выполняются для проверки того, что новый производственный код проходит новый тест и что другие тесты не дают сбоев. Рефакторинг: Устранить любые признаки плохого стиля кода как в производственном, так и в тестовом коде. Более интенсивную версию этого процесса можно найти в "Трех правилах TDD" от Дяди Боба.

Вся команда

В XP "клиент" – это не плательщик, а тот, кто фактически использует систему. XP утверждает, что клиент должен быть постоянно доступен и готов отвечать на вопросы. Например, в команду, разрабатывающую систему финансового администрирования, следует включить финансового администратора.

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

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

Улучшение конструкции

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

Небольшие выпуски

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

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

Стандарт кодирования — это согласованный набор правил, которому вся команда разработчиков соглашается следовать на протяжении всего проекта. Стандарт определяет единый стиль и формат исходного кода в выбранном языке программирования, а также различные конструкции и шаблоны программирования, которых следует избегать для снижения вероятности возникновения ошибок. Стандарт кодирования может представлять собой стандартные соглашения, установленные разработчиком языка (например, «Кодовые соглашения для языка программирования Java», рекомендованные Sun), или быть разработанным командой разработчиков самостоятельно. Сторонники экстремального программирования выступают за максимально самодокументируемый код. Это снижает потребность в комментариях к коду, которые могут устаревать и не соответствовать фактическому коду.

Коллективная собственность кода

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

Простая конструкция

Программисты должны придерживаться принципа "простота — лучшее" при разработке программного обеспечения. Каждый раз, когда пишется новый код, автор должен спросить себя: "Можно ли реализовать ту же функциональность более простым способом?". Если ответ утвердительный, следует выбрать более простое решение. Рефакторинг также следует использовать для упрощения сложного кода.

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

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

Устойчивый темп

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