Недавно обнаружил в загашниках интересный документ "Регламент разработчика XP". В 2004 году мы решили начать разработку очередного проекта по методологии XP. А поскольку большинство наших программистов знали об XP только то, что кодировать надо вдвоем, я написал небольшой документ, в котором на пяти страницах постарался изложить всю суть этой методологии, а также краткий свод требований для повседневной работы. Сегодня я перечитал этот док, и понял что ничего не могу в него ни добавить ни убрать. Значит он выдержал проверку временем. Итак, здесь выжимка из всего того, что должен знать каждый программист об XP.
Extreme Programming Essentials
Что такое XPЭкстремальное программирование (eXtreme Programming) – это методика разработки программного обеспечения, которая представляет собой набор принципов и практик, направленных на быстрое создание программного продукта, в максимальной степени удовлетворяющего потребности заказчика. Прилагательное «экстремальное» обозначает, что данная методика предполагает максимально интенсивное использование всех входящих в нее практик.
Основные ценности XP:
Общение (communication). Причина большей части проблем разработки программного обеспечения это недостаток общения между членами команды разработчиков, между разработчиками и заказчиками. Постоянные коммуникации обеспечивают большую согласованность процесса разработки.
- Простота (simplicity). Всегда старайтесь решить задачу самым простым способом из всех возможных. Сделай самую простую вещь, которая способна работать (Do simplest thing that could possibly work).
- Обратная связь. Чем раньше вы сможете получать отзывы от пользователей, тем лучше вы сможете удовлетворить требования заказчика.
- Храбрость (courage). Вы должны обладать храбростью для того, чтобы двигаться с максимальной скоростью и совершать правильные поступки (например, отказаться от написанного кода, обнаружив в нем серьезную ошибку и начать все заново).
Основные практики XP. Ниже перечислены 12 практик XP, которые должны использоваться комплексно и с максимальной интенсивностью. Поскольку каждая из этих практик опирается на другие и дополняет их.
- Процесс планирования. Планирование производится непрерывно в ходе всего процесса разработки с целью определения текущих задач приоритетов и сроков разработки.
- Тестирование. Любая разрабатываемая функциональность сопровождается тестами позволяющими определить, что код делает именно то, что от него требуется.
- Парное программирование. Любой код разрабатывается двумя программистами.
- Простой дизайн. Любая функциональность реализуется максимально простым образом. Дизайн системы постоянно перерабатывается с целью ее (системы, не дизайна) улучшения.
- Рефакторинг. Улучшение кода путем его переработки. Один и тот же код не должен встречаться в нескольких местах системы (once and only once).
- Коллективное владение кодом. Каждый из разработчиков отвечает за работоспособность всей системы.
- Постоянная интеграция. Новый код постоянно интегрируется в систему, и система постоянно поддерживается в работоспособном состоянии.
- Заказчик на месте разработки. Разработчик всегда может проконсультироваться с заказчиком по поводу функциональных требований. Заказчик всегда может увидеть, как исполняются его пожелания.
- Частые выпуски версий. Новые версии системы передаются заказчику как можно чаще, для того чтобы тот мог оценить в правильном ли направлении движется разработка.
- 40 часовая рабочая неделя. Разработчики не должны работать сверхурочно, так как от этого снижается производительность и качество работы.
- Стандарты кодирования. Разработчики придерживаются общих стандартов кодирования для облегчения понимания кода.
- Метафора системы. Простая аналогия, доступно и понятно описывающая предназначение и внутреннее устройство системы.
Взаимодействие заказчика и разработчика.Методология XP определяет две роли в процессе разработки: заказчик и разработчик.
Методология XP построена на принципах взаимодействия и тесной обратной связи между этими ролями. Предполагается, что заказчик активно участвует в процессе разработки с самого начала.
Обязанности и привилегии роли заказчика:
- Заказчик определяет функциональные требования к системе через «пожелания заказчика»
- Заказчик определяет приоритеты в реализации тех или иных требований.
- Заказчик определяет дату выпуска системы.
- Заказчик совместно с разработчиком определяет общий план разработки системы, а также план каждой итерации (для этого определяется перечень пожеланий, реализуемых в ходе итерации)
- Заказчик принимает результаты разработки отдельно по каждому из пожеланий.
- Заказчик может добавлять новые пожелания или снимать старые в ходе всего цикла разработки системы, вплоть до сдачи системы в эксплуатацию.
Имея столь широкие полномочия, заказчик несет полую ответственность за результаты проекта (включая обоснованность и коммерческую востребованность реализованного функционала).
Обязанности разработчика:
- Разработчик совместно с заказчиком определяет план разработки системы и планы каждой итерации.
- Разработчик определяет дизайн системы, максимально соответствующий требованиям заказчика.
- Разработчик информирует заказчика о возможных технических проблемах, или о возможных последствиях в ходе реализации тех или иных пожеланий заказчика.
- Разработчик оценивает затраты ресурсов на реализацию того или иного из пожеланий заказчика.
- Разработчик реализует пожелания заказчика в функционале системы.
- Разработчик информирует заказчика о ходе выполнения проекта, о возникающих проблемах и (или) отклонениях от графика.
До начала разработки заказчик совместно с разработчиком выполняет сбор требований, планирование и разработку общего дизайна (фаза анализа или нулевая итерация).
Разработка ведется короткими итерациями (2-3 недели). Для каждой итерации составляется план, состоящий из набора пожеланий заказчика. Заказчик определяет, какие из пожеланий следует реализовать в первую очередь. Разработчик оценивает затраты ресурсов на реализацию пожеланий и исходя из этого верстает план итерации. По окончании итерации заказчик принимает функционал по каждому из пожеланий.
В ходе реализации пожеланий разработчики решают все возникающие вопросы с представителем заказчика.
Процесс планирования разработкиРазработка ведется в соответствии с функциональными требованиями, формируемыми заказчиком (заказчиками). Основным элементом, в виде которого оформляются функциональные требования, является «пожелание заказчика».
Перед началом разработки выполняется так называемая фаза анализа или нулевая итерация, в ходе которой заказчик и разработчик формируют общее видение системы и первичный перечень пожеланий заказчика. Из полученного перечня пожеланий формируется предварительная функциональная спецификация. Разработчик выполняет предварительную оценку затрат ресурсов по каждому из пожеланий заказчика, а заказчик выставляет приоритеты для каждого пожелания. Данная информация используется при планировании итераций. В первые итерации попадают те пожелания, которые имеют наивысший приоритет.
Пожелания заказчика должны быть такими, чтобы их можно было реализовать за 2 – 4 дня разработки. Более крупные пожелания должны быть разбиты на несколько более мелких (конкретизированы).
Методология XP исходит из того, что не возможно сформулировать все функциональные требования перед началом разработки. Поэтому пожелания могут вноситься и удаляться в процессе разработки. Выполнять эти действия может только заказчик (либо с согласия заказчика – разработчик). Все практики XP нацелены на то, чтобы облегчить внесение таких изменений в ходе разработки.
При добавлении новых функциональных требований происходит перепланирование. Разработчик оценивает затраты ресурсов на реализацию новых пожеланий, а заказчик должен либо удалить другие свои пожелания на такую же сумму ресурсов, либо пересмотреть срок сдачи продукта (версии, итерации).
Планирование итерацииРазработка ведется итерациями. Продолжительность 2-3 недели. В начале каждой итерации выполняется планирование.
Планирование итерации. Планирование итерации состоит в том, что разработчик совместно с заказчиком выбирает из общего перечня пожеланий те, которые будут реализованы в ходе итерации. Далее разработчик уточняет у заказчика суть каждого пожелания, и разбивает его на отдельные задачи. Задачи отражают то как, будет реализовано пожелание, и представляют собой описания отдельных частей программы (бизнес объект, визуальная форма, сервис и т.д.). Для задач оцениваются необходимые затраты ресурсов, и на основе этих оценок уточняются затраты ресурсов по пожеланиям заказчика. Задачи должны формулироваться таким образом, чтобы реализация каждой из них занимала не более двух дней. Совокупная оценка затрат ресурсов по всем пожеланиям заказчика, включенным в итерацию не должна превышать совокупных наличных ресурсов итерации (число разработчиков умноженное на число рабочих дней итерации). Если затраты ресурсов по пожеланиям превосходят фонд ресурсов команды на итерацию, следует перенести лишние пожелания заказчика на следующую итерацию, либо разбить некоторые пожелания на более конкретные (мелкие) и часть из них перенести в следующую итерацию.
По окончании итерации заказчик совместно с разработчиком принимает реализованные в данной итерации пожелания. Если для пожелания существуют функциональные тесты, то приемка осуществляется на основании этих тестов. Если функциональных тестов нет, приемка осуществляется на основании описания пожелания заказчика. Отметку о том, что данное пожелание реализовано, ставит заказчик.
После того, как пожелание заказчика реализовано и принято заказчиком никакие доработки, переделки и т.д. по данному пожеланию более не выполняются. Все дополнительные доработки, устранение обнаруженных ошибок выполняются путем создания новых пожеланий заказчика.
Разработка функционала.Разработка прикладного функционала ведется в разрезе пожеланий заказчика. Для реализации каждого пожелания заказчика, как правило, выделяются два разработчика (если позволяет размер команды). Пара разработчиков, по своему желанию, может вести свою работу в режиме парного программирования (оба разработчика в паре последовательно работают над задачами), либо распределить задачи между собой и выполнять их параллельно.
Все вопросы, касающиеся толкования (понимания) пожелания заказчика разработчиками, или реализации изложенных в нем требований должны решаться совместно с представителем заказчика. Разработчики не должны делать никаких предположений по поводу функциональных требований, если они им не ясны или допускают двоякое толкование.
Разработчик должен стремиться реализовать пожелание заказчика
максимально простым способом (Do simplest thing that could possibly work). Не следует делать никаких предположений относительно будущей модернизации кода, если это прямо не вытекает из имеющихся в наличии пожеланий заказчика. Разработчик должен руководствоваться правилом
«Это нам не понадобится» YAGNI (You Aren't Gonna Need It), относительно любой функциональности, не описанной в текущих пожеланиях заказчика.
Весь разрабатываемый функционал должен сопровождаться модульными тестами. Нельзя добавить в проект функционал без модульных тестов. Исключение составляет тривиальный код (методы аксессоры, обертки, и т.п.), а также код, сгенерированный мастерами и генераторами кода (напр., DataSet).
В ходе разработки необходимо проводить постоянный рефакторинг кода, с целью повышения его надежности и простоты. Разработчик должен придерживаться правила трех О: “Once and Only Once”, что значит, избегать дублирования кода.
Каждый разработчик отвечает за
работоспособность всей системы. Перед внесением своих изменений следует убедиться (прогнав весь набор модульных тестов) в том, что вносимые изменения не нарушат работоспособность системы. Если такое случается, разработчик должен добиться правильного срабатывания всех тестов. Либо отменить свои изменения.
Разработчик должен как можно чаще интегрировать свой код в систему (соблюдая при этом требования предыдущего пункта). Следует избегать ситуации, когда файлы с исходным кодом остаются на check-out в VSS более чем на один день. Это существенно затрудняет последующую интеграцию кода.
Для разработчика определяется следующий регламент действий по реализации каждого пожелания заказчика:
- Для удобства, в случае, когда Solution продукта велик, разработчик создает локальный solution, в который он включает проекты, необходимые ему в разработке.
- Перед началом реализации пожелания следует взять из VSS последнюю версию исходных кодов системы.
- Для каждой задачи параллельно разрабатывается модульный тест и исходный код (предпочтительно разрабатывать сначала тесты, а затем код). Необходимо добиться срабатывания модульного теста.
- Модульный тест включается в состав общего плана тестирования, и проверяется срабатывание всех модульных тестов системы в тестовом solution продукта. Если какие либо из тестов перестали срабатывать, разработчик должен выяснить причину, и внести необходимые изменения в код системы, не зависимо от того, кто разрабатывал этот код. В случае затруднения разработчик может призвать на помощь автора кода. В любом случае разработчик должен уведомить членов команды о внесенных изменениях.
- Добившись срабатывания всех модульных тестов, разработчик может приступать к внесению нового кода в VSS (интеграции). Процедура интеграции следующая. Сохранив изменения в VSS (check-in), разработчик должен на специально выделенной для целей интеграции машине взять последнюю версию исходных кодов системы, собрать тестовый и основной solution системы и выполнить полный набор модульных тестов. Если какие либо из тестов не выполняются, следует либо выявить и устранить ошибки (не зависимо от того, к какой части кода системы они расположены) и добиться срабатывания тестов, либо откатить в VSS свои изменения. При необходимости разработчик должен проделать дополнительные действия (развертывание конфигурации импорт – экспорт прикладных данных и т.п.) необходимые для того, чтобы на интеграционной машине была развернута работоспособная, последняя версия разрабатываемого продукта.
- В случае если система оказывается в неработоспособном состоянии, ответственность за это лежит на том, чьи изменения привели к ошибке (а не на том, в чьем коде обнаружена ошибка).
В рамках команды проекта проводятся ежедневные короткие совещания (stand-up meeting), на которых разработчики рассказывают друг другу о проделанной за прошлый день работе, имеющихся проблемах и планах на текущий день. Вопросы по реализации конкретных пожеланий заказчика и решении возникающих проблем обсуждаются в частном порядке с участием заинтересованных лиц вне рамок данного совещания.