Единая команда


Мы хотим, чтобы заказчики, менеджеры и разработчики тесно сотрудничали, знали о проблемах друг друга и совместно работали над их разрешением. Но кто такой заказчик? Заказчиком XP-команды является лицо или группа лиц, которая определяет функции ПО и назначает им приоритеты. Иногда в роли заказчика выступает группа бизнес-аналитиков, специалистов по контролю качества и/или маркетологов, работающих в той же организации, что и разработчики. Иногда заказчиком является представитель, делегированный сообществом пользователей. Бывает, что заказчик - это тот, кто платит реальные деньги. Но в XP-проекте заказчик, как бы его ни определять, является членом команды, доступным для общения.

 

источник статьи


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


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


Пользовательские истории


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


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


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


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


Короткие циклы


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


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


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


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


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


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


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


Приемочные тесты


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


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


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


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


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


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


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


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


Разработка через тестирование


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


Промежуток времени между написанием тестов и кода очень краток, порядка минуты. Тесты и код эволюционируют вместе, причем тесты немного опережают код.


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


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


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


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


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


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


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


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


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


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


Умеренный темп


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


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


Открытое рабочее пространство


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


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


Может возникнуть опасение, что такое окружение отвлекает. Что из-за постоянного шума и разговоров ничего не удастся сделать. Но все не так страшно. Более того, в такой обстановке «боевого командного пункта» продуктивность не только не снижается, а, как показывает исследование Мичиганского университета, может даже возрасти вдвое.


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


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


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


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


Простота


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


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


Разработчик руководствуется тремя мантрами XP.

1. Выбирай самый простой способ, который будет работать. XP-команды всегда пытаются отыскать простейший вариант реализации текущего пакета историй. Если для текущих историй можно обойтись плоскими файлами, то СУБД, возможно, и не понадобится. Если для текущих историй достаточно простого соединения через сокет, то ни к чему ни брокер объектных запросов (ORB), ни веб-служба. Если для текущих историй не нужна многопоточность, то и включать ее не стоит. Мы всегда пытаемся найти самый простой способ реализации текущих историй. А затем выбираем решение, настолько близкое к идеалу простоты, насколько это практически возможно.


2. Тебе это не понадобится. Да, мы знаем, что в какой-то момент СУБД будет нужна. Мы знаем, что рано или поздно возникнет необходимость в ORB. Мы знаем, что в будущем придется поддерживать нескольких пользователей. Поэтому предусмотреть все это нужно уже сейчас, правда?


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


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


Источников дублирования кода много. Самые очевидные - копирование фрагмента с помощью мыши и вставка его в разные места. Встретив такое, мы создаем функцию или базовый класс. Но иногда два или более алгоритмов могут быть очень похожи и все же иметь тонкие различия. Тогда мы превращаем их в функции или пользуемся паттерном Шаблонный метод (Template Method) (см. главу 22). В общем, каким бы ни был источник дублирования, мы устраняем его.


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


Рефакторинг


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


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


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


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


Метафора


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


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


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


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


Часто метафора сводится к системе имен. Имена составляют словарь всех элементов системы и помогают выявить их взаимосвязи.


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


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


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


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


Заключение


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

источник статьи