Обратная связь также работает в масштабе недель и месяцев. Заказчики и те, кто обеспечивает функциональное тестирование системы, разрабатывают функциональные тесты для всех историй (говоря иначе – упрощенных тестовых случаев), реализованных в рамках системы. Таким образом они обладают обратной связью, которая обеспечивает их информацией о текущем состоянии используемой ими системы. Заказчики пересматривают график работ каждые две или три недели для того, чтобы убедиться, что скорость выполнения работ соответствует плану. В случае необходимости план пересматривается. Эксплуатация системы в реальных производственных условиях начинается, как только система становится способной решать хотя бы небольшую часть возлагаемых на нее обязанностей. В результате бизнес получает возможность на практике оценить, как именно выглядит система и в каком направлении ее лучше всего развивать в дальнейшем.
О том, что к эксплуатации системы следует приступать как можно раньше, следует рассказать подробнее. Одной из стратегий в процессе планирования является правило, в соответствии с которым наиболее полезные для заказчика истории реализуются программистами и начинают эксплуатироваться как можно раньше. Благодаря этому программисты получают обратную связь, которая обеспечивает их сведениями о качестве принятых ими решений. Процесс разработки начинает напоминать управление автомобилем – программисты прилагают усилия для того, чтобы проект развивался в направлении, удобном для заказчика, при этом колеса должны всегда оставаться на асфальте. Некоторые программисты занимаются разработкой системы длительное время до того, как она начнет эксплуатироваться в реальных рабочих условиях. Откуда же они могут узнать о том, что выполняемая ими работа действительно качественна и необходима?
В большинстве проектов используется прямо противоположная стратегия. Многие рассуждают так: Как только система начинает использоваться на реальном производстве, в нее нельзя будет внести «интересных» изменений, поэтому система должна находится в стадии разработки настолько долго, насколько это возможно.
В ХР делается прямо противоположное. В разработке – это временное состояние, в котором система находится в течение очень небольшого времени своей жизни. Будет значительно лучше, если система будет жить самостоятельной жизнью независимо от разработки. Необходимо позволить ей дышать и действовать самостоятельно. Необходимо поддерживать функционирование системы в условиях реального производства и одновременно с этим, разрабатывать новую функциональность. Необходимо обеспечить параллельную разработку и эксплуатацию, и чем раньше вы этого добьетесь, тем лучше.
Обратная связь работает совместно с коммуникацией и простотой. Чем более исчерпывающей является обратная связь, тем легче осуществлять коммуникацию. Когда кто-то недоволен написанным вами кодом и передает вам тестовый случай, который указывает на ошибку, это заменяет вам тысячу часов пространных дискуссий на тему эстетики программного дизайна. Если вы хорошо осуществляете коммуникацию, вы лучше знаете, что следует тестировать в системе. Простые системы тестировать проще. Разработка теста концентрирует ваше внимание на том, насколько простой может быть система; до тех пор, пока тест не сработает, вы не можете считать работу завершенной, а когда срабатывают все тесты, можно считать, что вы решили поставленную перед вами задачу.
В контексте первых трех рассмотренных ранее ценностей – коммуникации, простоты и обратной связи – необходимо действовать с максимально возможной скоростью. Если вы работаете со скоростью, которая не является абсолютно максимальной, это будет делать вместо вас кто-то другой, в результате этот кто-то прибежит к финишу первым и съест ваш обед вместо вас.
Я расскажу вам о том, как храбрость срабатывает в реальной жизни. В середине восьмой итерации включающего в себя 10 итераций рабочего графика (25 из 30 недель) первой версии первого крупного ХР-проекта команда обнаружила фундаментальную ошибку в архитектуре системы. Поначалу функциональные тесты указывали на хорошее качество разрабатываемой системы, однако позже количество набранных нами очков резко снизилось. В результате исправления одного дефекта обнаруживался другой дефект. Количество дефектов увеличивалось. Проблема была в архитектурном изъяне.
Для любопытных скажу, что мы работали над системой начисления выплат. Для хранения долгов компании перед сотрудниками использовались поля данных с названием Entitlement (жалованье), а для хранения долгов сотрудников перед другими людьми использовались поля с названием Deduction (вычет). Для некоторых людей использовалось отрицательное жалованье, в то время как вместо этого надо было использовать положительный вычет.
Команда поступила так, как должна была поступить. Когда все поняли, что путь вперед закрыт, они исправили архитектурный изъян. При этом половина всех используемых в отношении системы тестов перестала срабатывать. Однако в течение нескольких дней напряженных усилий по исправлению ситуации тесты снова начали срабатывать и качество системы, оцениваемое при помощи функциональных тестов, повысилось. Однако для того, чтобы поступить описанным образом, потребовалась отвага.
Еще один смелый ход – отказ от ранее разработанного кода. Представьте, что в течение всего рабочего дня вы работаете над реализацией некоторой функциональности. Работа идет неплохо, но когда вы близки к ее завершению, компьютер зависает. На следующее утро вы приходите на работу и в течение получаса восстанавливаете то, над чем работали весь предыдущий день, однако на этот раз код получается более чистым и более простым.
Используйте это. Если приближается конец рабочего дня и код все еще не поддается контролю, выбросьте его. Может быть, следует сохранить тестовые случаи, если вам понравился разработанный вами интерфейс. Однако это не обязательно. Возможно, следующим утром будет легче начать с нуля.
Возможно, перед вами три варианта дизайна. Вы можете потратить по одному дню на реализацию каждой из альтернатив для того, чтобы почувствовать, как они будут вести себя на практике. Затем выбросьте код и начните с нуля развивать тот вариант дизайна, который показался вам наиболее многообещающим.
Стратегия проектирования в ХР напоминает алгоритм взбирания на холм (hill climbing). Вы делаете простой дизайн, затем вы делаете его более сложным, далее вы его упрощаете, потом опять усложняете. Проблема подобных алгоритмов состоит в том, что вы ищете локальный оптимум, – при этом никакое незначительное изменение не может улучшить ситуацию, однако улучшения можно достичь, используя значительное изменение.
Достигнув локального оптимума вы, возможно, упускаете более эффективный вариант дизайна. Что поможет вам избежать этого? Как только у кого-нибудь из вашей команды возникает сумасшедшая идея, в результате реализации которой сложность всей системы существенно уменьшится, он обязательно попробует реализовать свою идею, если конечно, у него хватит храбрости. Иногда это срабатывает. Если у вас хватит храбрости, вы приступите к эксплуатации новой версии системы в промышленных условиях. Считайте, что теперь вы забираетесь на совершенно новый холм.
Если у вас нет остальных трех ценностей, храбрость сама по себе является обычным взломом (в самом уничижительном смысле этого слова). Однако в сочетании с коммуникацией, простотой и надежной обратной связью храбрость становится чрезвычайно полезной.
Коммуникация идет на пользу храбрости, так как благодаря коммуникации вы обретаете возможность для осуществления более рискованных и более заманчивых экспериментов. Тебе это не нравится? Я просто ненавижу этот код! Давай вместе посмотрим, в какой мере мы сможем переделать его сегодня днем. Простота идет на пользу храбрости, так как, обладая более простой системой, вы сможете позволить себе более смелые действия в ее отношении. Маловероятно, что вы нарушите ее функционирование по неизвестным причинам. Храбрость способствует простоте, ведь как только вы видите способ упростить систему, вы немедленно пробуете его реализовать. Надежная обратная связь идет на пользу храбрости, так как в процессе серьезной модернизации кода вы чувствуете себя значительно увереннее, если вы можете щелкнуть на кнопке и увидеть, что в результате тестирования все тесты показывают зеленый цвет. Если зеленым цветом окрашиваются не все тесты, вы переделываете или просто выкидываете свой код.