Основные практики ХР
Существует 13 основных практик экстремального программирования, которые могут помочь команде найти входы и выходы в разработке программного обеспечения и создавать легко изменяемый код. В отличие от scrum-практик, многие ХР-практики имеют особенности и направлены на решение самых распространенных проблем, провоцирующих создание плохого кода. В этих практиках все настолько тесно связано с программированием, что многие люди ошибочно считают: XP – это только для высококвалифицированных специалистов.
В этой главе мы поговорим о 10 основных практиках XP. Эти 10 практик разделены на четыре категории – программирование, интеграция, планирование и команда, – чтобы их легче было понять и удержать вас от заблуждения, будто методика XP пригодна только для суперразработчиков.
Практики программирования
Две основные практики XP – разработка через тестирование и парное программирование – предназначены специально для программистов и помогают им писать более качественный код. Они сосредоточены на нескольких важных аспектах разработки программного обеспечения. Созданием автоматизированных тестов перед написанием кода и его последующим тестированием команды повышают качество программного обеспечения. Работая вдвоем на одном компьютере, разработчики более тщательно вычитывают код в поиске ошибок.
Когда программист делает разработку через тестирование, которую обозначают аббревиатурой TDD (test-driven development), он создает автоматизированный тест перед тем, как начнет писать код. И пока код продукта не написан, тест будет завершаться провалом. Программист понимает, что код работает, когда тест оказывается пройден. Это создает петлю жесткой обратной связи, помогающую предотвратить появление дефектов: сначала написание проверочных тестов, затем создание кода, способного их пройти, поиск проблем и путей их решения и написание дополнительных проверочных тестов. Такие автоматизированные тесты обычно называют модульными. Слово «модуль» используется неслучайно: почти во всех языках программирования код очевидным образом разделяется на модули (классы, методы, функции, подпрограммы и т. д.), и практически любой язык предоставляет как минимум один способ создания и запуска автоматических тестов, которые привязаны к каждому из этих модулей. Создав вначале тесты, программист гарантирует, что все написанные им модули будут работать корректно.
Разработка через тестирование позволяет убедиться лишь в том, что каждый отдельно взятый модуль работает. Это также помогает командам предотвратить некоторые из самых распространенных и серьезных проблем, которые могут создать трудности в ходе поддержки кода. Можно внести изменения в одну часть кода и обнаружить, что неожиданно появились ошибки в другой части, которая, казалось бы, никак не связана с первой. И это только потому, что разработчик не подозревал о существовании зависимости между ними. Когда программист пишет модульные тесты, использующиеся каждый раз при сборке кода, эти автоматизированные тесты помогают избежать появления зависимостей, которые, оставшись невыявленными, приведут к немедленному сбою. Тесты помогают программисту заметить проблему, прежде чем она окажется встроенной в общий код и ее будет трудно удалить. Кроме того, модульные тесты помогают разработчикам писать код, который легче использовать повторно. Например, программист может создать класс Java, работа с которым чрезмерно усложнена: использовать в нем сбивающие с толку имена, неудобную инициализацию или другие структурные проблемы, которые смогут легко пробраться в код любого разработчика. Когда программист создает модульный тест, использующий такой класс, изъян может стать очевидным и, так как код класса еще не написан, разработчику несложно устранить этот изъян. Затем модульный тест становится частью исходного кода, так что другие программисты могут опираться на него, чтобы увидеть, как этот метод предполагалось использовать.
Вторая основная ХР-практика, ориентированная на написание кода, – это парное программирование. В команде, занимающейся парным программированием, два разработчика пишут код, сидя за одним компьютером. В большинстве случаев один программист сидит за клавиатурой, а другой наблюдает и они постоянно обсуждают, что делают. Команды, работающие в парах, вносят гораздо меньше ошибок, потому что за процессом внимательно следят две пары глаз. Парная работа также помогает уменьшить усталость, потому что один программист может печатать, когда другой устал. Эффективные команды парного программирования обсуждают идеи и подходы, постоянно устраивают мозговые штурмы и поэтому более инновационны. Они также несут ответственность друг перед другом за правильное применение практики: одному проще словчить, а под наблюдением партнера сделать это гораздо сложнее. Многие разработчики рассказывали нам, что программисты в парах пишут код быстрее и лучшего качества, чем работая по отдельности.
Практики интеграции
Существуют две основные XP-практики, которые мы относим к категории «интеграция». Первая – это десятиминутная сборка. Команда создает автоматизированную сборку для всей кодовой базы, которая длится 10 минут. Эта сборка включает в себя автоматический запуск всех модульных тестов и генерацию отчетов с положительными и отрицательными результатами.
«Десять минут» может звучать как произвольная величина, но с точки зрения команды она имеет смысл. Если сборка проекта занимает более 10 минут, то члены команды запускают ее гораздо реже. Но для команды очень важно использовать ее часто, потому что это быстро выявляет проблемы. Например, в сборке запускаются модульные тесты, поэтому после ее завершения команда знает, достигла ли она нужного качества.
Иными словами, она позволяет быстро получить ответ на вопрос «Работает ли еще наш код?». И благодаря тому, что сборка довольно короткая, команда будет запускать ее часто, а каждый член команды получит постоянно обновляемую картину качества кода.
Другая интеграционная практика – это непрерывная интеграция. Она реализуется благодаря набору инструментов, позволяющих нескольким членам команды одновременно работать с одной версией исходного кода. Если несколько членов вашей команды должны одновременно работать с одними и теми же файлами, то они не могут использовать одну физическую копию файла на всех. Иначе они бы постоянно затирали изменения друг друга. Поэтому команда будет применять специальную систему контроля версий, которая имеет централизованный (или децентрализованный) основной набор файлов. Отдельные разработчики будут выписывать из него, или копировать, нужные файлы, которые будут использоваться только этим программистом (что часто именуют помещением в так называемую песочницу). Разработчик будет трудиться над копией кода в своей «песочнице» и периодически отправлять изменения обратно в общее хранилище.
Проблема в том, что слишком часто разработчик, внося измененную версию программы, обнаруживает конфликт своего кода с изменениями, незадолго до этого внесенными другим программистом. В большинстве случаев этот конфликт выявляется сразу же при попытке выгрузить личную копию в общую базу кода, которая перестает компилироваться. Но временами проблемы оказываются более серьезными и скомпилированная программа ведет себя неправильно. Причина в том, что один код был заменен конфликтующим с ним кодом, взятым из другой «песочницы». Все эти проблемы проявятся, когда будет проведена интеграция системы из различных частей, написанных разными программистами.
И вот тут вступает в дело практика непрерывной интеграции: команда должна достаточно часто собирать код и отслеживать ошибки компиляции или сбои модульных тестов. Многие команды настроят сборочный сервер для периодической компиляции кода из хранилища, запуска полученной сборки и уведомления команды, если обнаружатся ошибки. Но создание сервера непрерывной сборки – это лишь одна часть непрерывной интеграции. Непрерывная интеграция означает, что каждый член команды постоянно содержит свою копию исходного кода в актуальном состоянии. Члены команды периодически интегрируют последнюю версию кода из хранилища обратно в свои «песочницы». Команды, применяющие парное программирование, порой пользуются физическим маркером сборки. Это может быть плюшевая или резиновая игрушка (забавная и заметная, чтобы сразу было видно, у кого она находится). Она переходит от пары к паре. Когда пара получает этот символ, наступает ее очередь интегрировать последнюю версию кода из хранилища к себе, исправить все найденные проблемы интеграции, а затем передать маркер сборки следующей паре. Это гарантирует, что проблемы интеграции будут обнаружены на ранних стадиях и исправлены.
Практики планирования
Для управления своими проектами XP-команды используют итеративную разработку. Как и в Scrum, практики XP-планирования основаны на большом цикле долгосрочного планирования, который разбит на короткие итерации. В практике недельного цикла XP-команды используют итерации длиной в одну неделю совместно с практикой историй (это то же самое, что и пользовательские истории, о которых вы уже знаете). Каждый цикл начинается с совещания, посвященного планированию, где члены команды проводят обзор достигнутых результатов, работают с клиентами, чтобы выбрать истории для итерации, а затем разбивают их на задачи, которые оцениваются и передаются разработчикам.
Это вам уже знакомо, потому что это очень похоже на scrum-планирование. Действительно, многие XP-команды в точности перенимают практики scrum-планирования (которые считаются популярными гибридами Scrum и ХР, описанными в отчете VersionOne State of Agile, упоминавшемся в ). Закончив планирование, команда посвящает первую часть итерации написанию автоматических тестов для историй и задач, а остальное время итерации пишет код, способный пройти эти тесты. Но вместо процесса самоорганизации некоторые XP-команды помещают все задачи на данную итерацию в очередь. Каждый разработчик берет следующую задачу из этой очереди после завершения текущей. Это гарантирует, что разработчики не выбирают свои любимые задачи и они распределяются равномерно между всеми.
Для долгосрочного планирования XP-команды используют практику квартального цикла. Раз в квартал команда собирается, чтобы проанализировать ход работ над проектом. На этих встречах XP-команды обсуждают темы, то есть те идеи из реального мира, которые они могут использовать, чтобы связать воедино истории своего проекта. Такие дискуссии помогают выяснить, какие истории необходимо добавить в проект, и поддерживают связь команды с реальными проблемами бизнеса, которые должно решить программное обеспечение. Также обсуждаются внутренние и внешние трудности, которые испытывает команда, повторяющиеся ошибки и еще не внесенные исправления. Оцениваются результаты, которых добилась команда, насколько хорошо удалось удовлетворить потребности клиентов и как в целом продвигается проект. Некоторые XP-команды склонны использовать ту же практику ретроспектив, что и scrum-команды.
И последняя из ХР-практик, посвященных планированию, – временной запас. Она позволяет команде добавлять мелкие, менее приоритетные истории в каждый недельный цикл. Во время планирования эти истории разбивают на задачи, но к ним не приступают до конца итерации. И тогда, если команда сталкивается с неожиданными проблемами, она исключает из итерации эти «запасные истории» и все-таки поставляет работающее ПО в конце цикла. Как и в других методах итеративной разработки, XP-команды поставляют в конце итерации только полностью законченный функционал. Это означает, что он работает, все тесты пройдены и его можно продемонстрировать пользователям.
Командные практики
XP затрагивает как программирование, так и совместную работу команд. Эта методика включает в себя две основные практики, помогающие командам сплотиться, – «командные практики». Первая – коаллокация, когда команда располагается в одном помещении. Люди в команде работают лучше, когда сидят рядом друг с другом и могут легко коммуницировать. Многие люди не осознают, что, хотя программирование – это индивидуальный труд и зачастую выполняется в одиночку (за исключением парного программирования), работа в команде разработчиков требует высокой социальной активности.
Члены команды постоянно консультируются друг с другом, советуются и предупреждают о возможных проблемах. Если команда располагается в помещении типа open space, такая социализация обеспечивается естественным образом. По поводу того, каким должно быть открытое рабочее пространство, ведется много споров. Чтобы работать эффективно, программисты должны быть защищены от отвлекающих факторов. Многие из них ценят уединенность и размещают свои мониторы так, чтобы проходящие мимо люди не могли видеть экран. Популярное решение этой проблемы – модель планировки офиса «пещеры и поляны», описанная Стюартом Брэндом в книге How Buildings Learn. В его схеме имеются как отдельные, так и общие рабочие места для программистов, которые одной стороной выходят в общий зал со столами для проведения совещаний и компьютерами для работы парами.
Следующая основная практика XP-команд – это информативное рабочее пространство, в котором производственная среда команды устроена таким образом, чтобы важная информация о проекте автоматически передавалась всем участникам. Один из наиболее популярных способов для этого – применение большой доски задач и диаграммы выполняемых работ (диаграммы сгорания), которые висят так, чтобы каждый мог их видеть. Наглядное размещение постоянно обновляемой информации о проекте позволяет каждому члену команды знать, на какой стадии находится проект, и принимать правильные решения. Такие диаграммы и другие способы, которые команда использует для отображения данных, делающие рабочее пространство более информативным, называются излучателями информации. Они автоматически передают текущую информацию о проекте всем, кто на них взглянет.
Большие, наглядные диаграммы – не единственный способ сделать рабочее пространство информативным. Когда у членов команды появляются вопросы, они сталкиваются с проблемами или им необходимо обговорить какие-то детали, они организуют обсуждение. Если такие дискуссии происходят в общем рабочем пространстве, а не в закрытых конференц-залах, то окружающие невольно слышат их и впитывают информацию о происходящем. Когда члены команды автоматически вбирают информацию о проекте – неважно, из диаграмм, разговоров или иным способом, – это называется осмотической коммуникацией. Командам необходимо найти баланс между пользой такой коммуникации и ее отвлекающим влиянием, и XP-команды становятся успешными, если им удается его отыскать.
Почему важны информационные рабочие пространства? Суть в том, чтобы помочь команде принимать лучшие решения и дать ей больше контроля над ходом проекта – подобно тому, как доски задач помогают scrum-командам. Главное, что информация предназначается для всей команды, а не только для ее руководителей или менеджеров. Это демократизирует распространение информации и обеспечивает ею всю команду без какой-либо фильтрации. Чем больше сведений о проекте доступно команде, тем сильнее каждый ее участник может влиять на ход событий.
Почему команды противостоят изменениям и чем могут помочь практики
Никто не любит менять уже написанный код по требованию заказчика. Внесение изменений в конце проекта может вызывать различные эмоции – от раздражения до озлобления и даже до ощущения надвигающейся катастрофы, если в ближайшие полтора месяца предстоит работа без выходных только потому, что клиент не продумал все до конца.
Именно поэтому разработчики часто жалуются, что бизнес-пользователи постоянно меняют свои решения. Очень часто, когда проект уже начался, можно услышать такие разговоры: «Так вы хотите это изменить? Если бы я знал, то написал бы код совершенно иначе! Почему в начале проекта вы не объяснили нам, чего именно хотите?»
Рис. 6.2. Каждый руководитель проекта знаком с ощущением беспомощности из-за необходимости внесения изменений, которые разработчики не в состоянии выполнить. Каждому разработчику знакомо чувство тревоги, когда, казалось бы, небольшие изменения в коде разрастаются как снежный ком и требуют слишком много времени
И разве можно их за это винить? Команды сопротивляются этим изменениям, особенно в конце проекта, потому что им предстоит дополнительная работа. И не просто работа – а самый плохой ее вариант, самый раздражающий. Изменения заставляют вас возвращаться к тому, что вы считали законченным, разносят сделанное в пух и прах и вынуждают переписывать большие куски кода заново. И это не просто разочаровывающая работа: ваша команда вложила в нее много душевных сил, решила массу проблем и нашла наиболее элегантные решения. А теперь вам говорят, что нужно разрушить созданный командой Тадж-Махал, потому что на самом деле нужна была Эйфелева башня.
Но у медали есть и другая сторона. Пользователь или руководитель, просивший в начале проекта одно, а к концу изменивший свои требования, делает это вовсе не с целью дезорганизовать команду. Мы уже знаем, что раздробленное видение приводит к плохим результатам, так что давайте попробуем взглянуть на эту проблему со стороны пользователя. Ему нужно программное обеспечение, позволяющее выполнять свои задачи, а это означает, что он должен сотрудничать с командой разработчиков. Теперь его просят ответить на вопросы, которые ему не совсем понятны: «Кто должен иметь доступ к этой функции?»; «Сколько людей будут использовать эту систему одновременно?»; «Каково допустимое время между нажатием кнопки “начать” и отображением результатов?»; «Какова правильная последовательность действий?»
То, что начиналось как встреча, на которой пользователь пытался объяснить свою проблему, каким-то образом превратилось в бесконечный поток обращенных к нему технических вопросов, на которые он не знает ответов. А время-то идет, и он чувствует: если не дать ответы на все вопросы, то команда отложит выполнение проекта и обвинит в этом его. (Будем честны: именно так она, скорее всего, и поступит.) Все знают, что создание ПО – дорогое удовольствие, а пользователь – не специалист в этом, поэтому дает самый лучший ответ, на который способен. И когда встреча заканчивается, он не мешает команде двигаться вперед и сжигать бюджет.
Как решить эту проблему? Кто прав?
Гибкие методологии, и в частности XP, с готовностью признают следующее: невозможно заранее знать в точности, что мы собираемся создавать, а наиболее эффективный способ это описать – начать работу над проектом. В данных методологиях исчерпывающую документацию заменяет работающее ПО, поскольку самый эффективный способ получить от пользователей обратную связь – это написать часть программы и отдать им для практического применения.
Поэтому, вместо того чтобы настраивать команду против изменений, возможно, стоит создать условия, при которых она сможет справиться с этими изменениями без шумных распрей и работы в выходные? Никто не любит вносить изменения, но, возможно, вам удастся найти способ ограничить влияние на проект каждого из них, причем не только в том, что касается целостности кода, но и в отношении морального состояния команды и пользователей.
Именно так поступают команды XP и называют такой стиль адаптацией к изменениям. Команды XP признают, что изменения – это не только неизбежное зло. Лишь в случае частого получения обратной связи от пользователей и быстрого реагирования на нее они смогут создать действительно лучшее ПО для своих клиентов. Эти команды готовы к изменениям и даже планируют их. Они не воспринимаются как плохие новости, которые всегда сопровождаются поиском виноватого, прозевавшего часть требований. Правильное мышление для XP означает не только принятие изменений, но и желание иметь их.
Адаптация к изменениям имеет два аспекта: степень охвата проекта и собственно база кода. Влияние изменений на код иногда бывает значительным – изменение, которое первоначально казалось маленьким, может ошеломить команду, потребовав существенного переписывания. Команды будут говорить о необходимости «разодрать код» и заделать дырки «скотчем, скрепками и жевательной резинкой». Мы рассмотрим тему адаптации к изменениям в . А пока обсудим, как XP-команды приспосабливаются к изменениям масштабов проекта, функциональности программного обеспечения и его поведения.
Так как же основные практики XP помогают командам делать это?
Планирование
Когда команды итерационно планируют и поставляют работающее программное обеспечение в конце каждой итерации, они постоянно получают обратную связь. Все в команде знают, что они активно просят об обратной связи. Ведь намного проще справиться с изменениями, если вы тот, кто попросил об этом в первую очередь.
Команда
Решать проблемы гораздо проще, если поблизости есть люди, готовые помочь. Когда команды располагаются рядом, они выявляют проблемы намного раньше. А информационное пространство помогает сделать так, чтобы все работали над одной и той же проблемой. Это позволяет всем членам группы взять под контроль происходящие изменения и не быть застигнутыми врасплох возможными неожиданностями. Отдельные члены команды получают автономность, которая нужна им для принятия решений, влияющих на их код и даже жизнь.
Интеграция
Одна из самых неприятных проблем, вызванных неожиданными изменениями, – это то, что они распространяются по всей базе кода. Если вы работаете с постоянными изменениями, то вам важно узнать о них как можно раньше – вот почему командные практики действительно полезны. Но человек все равно будет застигнут врасплох, если изменение, внесенное в базу кода его коллегой, вызовет неожиданную ошибку в той части кода, над которой работает он сам. Благодаря непрерывной интеграции (которую осуществлять легче, потому что наша сборка работает быстро) мы узнаем об этой проблеме очень быстро и исправим ее раньше – до того, как она станет нашей головной болью.
Программирование
Как непрерывная интеграция помогает выявлять изменения? Мы создали набор модульных тестов, которые запускаем каждый раз при выполнении интеграции кода. Поэтому, когда один из членов команды добавляет изменения, он запускает все тесты, в том числе и для той части кода, над которой работают все остальные ее участники. Если один из этих тестов терпит неудачу, то мы сможем работать вместе – и даже парами, – чтобы решить эту проблему в обеих конфликтующих частях кода.
Когда все эти практики работают вместе, то изменения – даже крупные – испытывают меньшее негативное влияние. Это помогает команде понять, что с изменениями можно справляться легче.
Ключевые моменты
Когда XP-команды используют разработку через тестирование, первым делом они создают модульные тесты, выражающие поведение будущего кода, а затем пишут код, который сможет их пройти. Это создает петлю обратной связи, помогающую предотвратить появление дефектов.
Команды создают десятиминутную сборку, или автоматизированную сборку, которая выполняется не более чем за 10 минут.
Отдельные разработчики используют непрерывную интеграцию, чтобы постоянно учитывать изменения коллег, поэтому у каждого из них «песочницы» соответствуют текущему состоянию проекта.
XP-команды применяют итерации с циклами в неделю и квартал, а также истории так, как это делают scrum-команды.
Команды добавляют незначительные, с низким приоритетом задачи в каждый недельный цикл, чтобы создать временной запас.
Когда XP-команды сидят вместе, они периодически впитывают информацию о проекте через осмотическую коммуникацию.
XP-команды работают в информационном рабочем пространстве, которое использует излучатели информации, такие как настенные диаграммы выгорания, автоматически передающие ее людям, находящимся поблизости.
Описание: команда занимается разработкой фантазийного баскетбольного сайта
Джастин – первый разработчик
Даниэль – второй разработчик
Бриджит – менеджер проекта