Обратите внимание, это означает, что иногда вы должны сделать больше работы, чем это на самом деле необходимо для того, чтобы добавить в программу новую возможность. Однако, работая в этом ключе, вы обеспечиваете снижение затрат, связанных с добавлением в программу последующих возможностей. Переработав код, вы упрощаете его дальнейшую модернизацию. Вы не выполняете переработку исходя из предварительных нечетких размышлений, напротив, вы перерабатываете код тогда, когда система нуждается в этом. Когда при добавлении новой возможности вы дублируете код, это означает, что система просит вас выполнить переработку.
   Если программист видит некоторый черновой способ обеспечить выполнение теста, для реализации которого потребуется одна минута, и, помимо этого, он также видит другой, более элегантный способ обеспечить выполнение теста, предусматривающий также упрощение дизайна, но для реализации которого требуется десять минут, программист должен предпочесть второй способ, то есть потратить больше времени, но в результате получить более простой и более элегантный дизайн. К счастью, в рамках ХР вы получаете возможность вносить в дизайн системы любые, даже самые радикальные изменения, делая это небольшими, малорискованными шагами.
Программирование парами
   Весь код системы вплоть до ее внедрения в производство пишется парами программистов, каждая из которых работает на одном компьютере, оснащенном одной клавиатурой и одной мышью.
   В каждой паре существуют две роли. Один партнер, в руках которого находится клавиатура и мышь, думает о том, как прямо сейчас реализовать некоторый метод самым лучшим образом. Второй партнер думает более стратегически:
   • Сработает ли используемый подход в целом?
   • Какими могут быть другие, еще не рассмотренные тестовые случаи?
   • Существуют ли какие-либо способы упростить всю систему таким образом, что текущая проблема просто исчезнет?
   Состав пар меняется динамически. Партнеры, которые утром входили в состав одной пары, днем могут стать членами совершенно других пар. Если вы отвечаете за решение задачи в области, которая является для вас малознакомой, вы можете попросить составить вам компанию кого-либо, кто недавно работал в этой области. Скорее всего, вы побываете в паре с каждым из членов вашей команды.
Коллективное владение
   Любой член команды, который видит возможность добавить что-либо в любой раздел кода системы, может сделать это в любой подходящий для этого момент времени.
   Сравните это с двумя другими моделями владения кода – полное отсутствие владения и индивидуальное владение. В давние времена различными кусками кода программы никто не владел. Если кто-либо желал изменить какой-либо код, он мог сделать это в соответствии со своими собственными пожеланиями. Результатом был хаос, в особенности если приходилось иметь дело с объектами, в которых взаимосвязь между строкой кода в одном месте и строкой кода в другом месте нельзя было в точности установить статически. Код разрастался очень быстро, и с такой же скоростью он стремительно терял стабильность.
   Чтобы подвести ситуацию под контроль, программисты стали использовать индивидуальное владение кодом. Единственным человеком, кто обладал правом внесения в некоторый фрагмент кода изменений, являлся официальный владелец этого кода. Если кто-либо, не являющийся владельцем, видел, что код необходимо изменить, он должен был обратиться с соответствующей просьбой к владельцу. В результате такой практики действительный код системы начинал расходиться с тем, каким его хотели бы видеть работающие в рамках проекта программисты. Изменение кода в рамках подобного подхода превращалось в своего рода бюрократическую процедуру – люди начинали избегать обращаться к владельцу кода для того, чтобы внести в код желаемые изменения, вместо этого они предпочитали работать с тем, что есть. В конце концов, внести изменение требуется прямо сейчас, а не спустя некоторое время. Таким образом, код оставался относительно стабильным, однако он не эволюционировал с достаточно большой скоростью. А когда владелец кода находил другую работу и уходил из команды... возникали серьезные проблемы.
   В рамках ХР ответственность за весь код системы лежит на всех членах команды. Нельзя сказать, что каждый член команды хорошо знает каждую часть кода, однако можно сказать, что каждый член команды знает, по крайней мере, что-то о каждой части. Если пара программистов работает над решением некоторой задачи и видит, что для упрощения работы требуется внести модификации в некоторую часть кода, тем самым улучшив этот код, изменения вносятся немедленно, благодаря чему решаемая этой парой задача упрощается. 
Постоянно продолжающаяся интеграция
   Код интегрируется и тестируется каждые несколько часов, минимум один раз в день. Для того чтобы обеспечить это, проще всего выделить для этой цели один специально предназначенный для этого компьютер. Когда этот компьютер освобождается, пара, у которой имеется код, подлежащий интеграции, садится за интеграционный компьютер, загружает текущую версию системы, добавляет в нее свои собственные изменения (проверяя и устраняя любые несоответствия и конфликты) и запускает тесты до тех пор, пока все они не сработают (все 100% тестов).
   Интеграция одного набора изменений за один раз отлично срабатывает, так как становится очевидным, кто именно должен исправить тест, который не сработал, – мы должны, так как, должно быть, именно мы его сломали. Это связано с тем, что предыдущая пара, которая выполняла интеграцию, добилась срабатывания всех 100% тестов. И если мы не добьемся срабатывания всех 100% тестов, мы должны выкинуть из системы все, что мы написали, и начать решать задачу заново, так как очевидно, что в этом случае, приступая к решению, мы просто не знали всего того, что требуется для разработки требуемого кода (возможно, мы не знаем всего необходимого и сейчас).
40-часовая рабочая неделя
   Я хочу быть свежим и энергичным каждое утро, равно как и уставшим и удовлетворенным каждый вечер. Каждую пятницу я хочу быть уставшим и удовлетворенным настолько, чтобы в течение последующих двух дней чувствовать себя в состоянии думать о чем-либо, не связанном с работой. После этого, в понедельник, я хочу приходить на работу с горящими глазами и головой, наполненной идеями.
   Конечно же, для этого необязательно, чтобы рабочих часов в неделе было бы ровно 40. Разные люди способны эффективно работать в течение различного времени. Один человек не может концентрировать свое внимание дольше, чем в течение 35 рабочих часов, другой способен успешно действовать в течение 45 часов в неделю. Но никто не способен работать по 60 часов в неделю на протяжении многих недель и при этом оставаться свежим, творческим, внимательным и уверенным в своих силах. Ни в коем случае не делайте этого!
   Работа во внеурочное время – это признак серьезных проблем в проекте. В рамках ХР действует очень простое правило – нельзя работать во внеурочное время две недели подряд. В течение одной недели можно поднапрячься и поработать несколько лишних часов. Но если в очередной понедельник вы приходите на работу и объявляете: Чтобы достичь поставленных целей, мы должны снова работать допоздна, это означает, что у вас возникли проблемы, которые вы не сможете решить простым увеличением рабочего времени.
   Отпуск является близкой к этому темой для обсуждения. Европейцы часто отдыхают в течение двух, трех или четырех последовательных недель. Американцы редко когда берут для отдыха больше чем несколько дней подряд. Если бы это была моя компания, я настаивал бы на том, чтобы люди отдыхали в течение двух последовательных недель ежегодно и при этом у них в запасе было бы не менее одной или двух недель дополнительно для более коротких отпусков.
Заказчик на месте разработки
   Для ответов на возникающие вопросы, решения споров и установки мелкомасштабных приоритетов рядом с командой разработчиков должен постоянно находиться реальный заказчик. Под термином реальный заказчик я подразумеваю человека, который действительно пользуется системой, когда эта система работает в производственных условиях. Например, если вы разрабатываете систему обслуживания клиентов, заказчиком будет служащий по работе с клиентами, пользующийся этой системой. Если вы разрабатываете систему обмена долговыми обязательствами, заказчиком будет биржевой брокер, работающий с этой системой.
   Основным препятствием для воплощения этого правила является то обстоятельство, что реальные пользователи разрабатываемой системы обходятся для заказчика слишком дорого в смысле рабочего времени. Иногда менеджерам заказчика жалко жертвовать одним из реальных служащих компании только для того, чтобы он постоянно находился вместе с разработчиками и отвечал на их вопросы. Менеджеры должны решить, что является для них более важным – ускорение и повышение качества разработки или рабочее время одного или двух сотрудников. Если программная система не приносит бизнесу больше, чем приносит ему один из сотрудников предприятия, скорее всего, такая система не стоит того, чтобы ее разрабатывать и внедрять на производстве.
   Кроме того, утверждение, что представитель заказчика, работающий вместе с командой, не может заниматься некоторыми своими повседневными делами, на самом деле не верно. Даже такие творческие люди, как программисты, не могут генерировать вопросы непрерывно в течение 40 часов каждую неделю. Конечно, сотрудник предприятия-заказчика обладает тем недостатком, что он физически удален от тех людей, с которыми он должен взаимодействовать, однако при этом у него будет достаточно времени для выполнения некоторой своей обычной работы.
   Недостатком такого подхода является то, что в случае, если проект в конце концов умирает, то сотни часов, которые сотрудник предприятия заказчика потратил на помощь и консультации разработчиков, оказываются временем, потраченным впустую. Получается, что заказчик потерял работу, которую его сотрудник делал вместе с разработчиками, а также он потерял работу, которую его сотрудник мог бы сделать в соответствии со своими прямыми обязанностями, если бы его рабочим временем не пожертвовали ради поддержки разработки проекта. ХР делает все возможное для того, чтобы проект не умирал.
   Однажды я работал над одним проектом, и фирма-заказчик с большой неохотой выделила нам одного реального сотрудника, но только ненадолго. После того как мы завершили первый этап разработки и успешно внедрили первую версию системы на производстве, когда стало очевидным, что система может продолжать эволюционирование, менеджеры заказчика выделили нам трех реальных сотрудников. Компания-заказчик пришла к выводу, что сможет получить от системы больше прибыли, если пожертвует большим количеством своих сотрудников.
Стандарты кодирования
   Если мы собираемся перебрасывать программистов с разработки одной части системы на разработку другой части системы, обеспечивать постоянную смену партнеров в парах по несколько раз на дню, обеспечивать постоянную переработку кода программистами, которые этот код не писали, мы просто не можем позволить себе использовать в рамках одного проекта применение нескольких разных стилей кодирования. Спустя некоторое время работы над системой уже нельзя будет сказать точно, какой именно член команды написал тот или иной код.
   Стандарт должен требовать от разработчиков приложения минимально возможных усилий для реализации той или иной возможности. Он должен способствовать воплощению на практике правила трех О – Once and Only Once (запрет на дублирование кода). Стандарт должен способствовать коммуникации. Наконец, стандарт должен быть добровольно воспринят всей командой разработчиков. 

Глава 11.
Как это работает?

   Методики поддерживают друг друга. Слабость одной из них покрывается за счет силы других.
   Подождите-ка минутку! Ни одна из перечисленных ранее методик не является уникальной или оригинальной. Все они используются уже давно, с самого начала эпохи программирования. От многих из этих методик в свое время отказались в пользу других, более сложных и более высокоуровневых, так как их слабость стала очевидной. Не является ли ХР слишком упрощенным взглядом на разработку программ? Прежде чем мы продолжим, мы должны убедиться в том, что эти рассмотренные ранее простые методики не уничтожат нас точно так же, как они уничтожили множество программных проектов десятилетия назад.
   Благодаря тому что у нас появилась возможность заменить экспоненциальную кривую роста затрат на пологую, почти асимптотическую линию, мы вновь можем с успехом использовать рассмотренные ранее методики и тем самым существенно повысить эффективность нашей работы. Каждая из этих методик, как и раньше, обладает некоторыми недостатками, но что, если мы попытаемся устранить недостатки одной методики за счет достоинств других методик? Должно быть, мы сможем существенно упростить себе работу.
   В данной главе мы вновь рассмотрим описанные ранее методики, но на этот раз с несколько другой стороны. Мы попытаемся проанализировать, что делает ту или иную методику непригодной для использования. Мы также продемонстрируем, каким образом недостатки одной методики компенсируются достоинствами других методик. В данной главе показывается также, каким образом весь механизм ХР может работать на благо разработки программного продукта.
Игра в планирование
   Вы не можете начать работу над проектом, имея на руках лишь грубый, нечеткий план предстоящей работы. Вы не можете постоянно обновлять ваш план – это потребовало бы слишком много времени, и в результате заказчики остались бы недовольны.
   Однако в ХР:
   • заказчики выполняют обновление плана самостоятельно, на основании оценок, которые делаются программистами;
   • в самом начале работы вы обладаете планом, достаточно четким для того, чтобы дать заказчикам представление о том, чем может стать для них разрабатываемая система через пару лет;
   • вы выпускаете продукт небольшими версиями, благодаря чему любая ошибка в плане будет портить жизнь заказчику лишь в течение нескольких недель или месяцев, но не более того;
   • заказчик в лице своего представителя постоянно находится рядом с разработчиками, благодаря чему он может быстро наметить потенциальные изменения в плане и быстро внести в него необходимые улучшения.
   При выполнении этих условий вы, скорее всего, можете без опасений приступать к разработке, имея на руках лишь упрощенный план, с намерением в дальнейшем постоянно пересматривать его и вносить в него изменения.
Небольшие версии
   Вы не можете приступить к эксплуатации системы уже через несколько месяцев работы над проектом. Вы определенно не можете выпускать новые версии системы каждый день или каждые несколько месяцев.
   Однако в ХР:
   • игра в планирование помогает вам работать над наиболее важными историями, поэтому даже небольшая система в состоянии приносить пользу бизнесу;
   • вы занимаетесь интеграцией системы постоянно и ежедневно, поэтому затраты, связанные с формированием очередной полноценной рабочей версии, существенно сокращаются;
   • в процессе разработки вы постоянно выполняете тестирование системы, благодаря этому количество дефектов в системе настолько мало, что вам не требуется заниматься длительным и болезненным предпродажным тестированием продукта перед тем, как вводить его в эксплуатацию;
   • вам достаточно сформировать простой дизайн, который достаточен для текущей версии продукта, этот дизайн вовсе не обязан быть ориентированным на использование в течение всего времени жизни системы.
   При выполнении этих условий вы, скорее всего, можете без опасений выпускать продукт небольшими версиями, внедряя его в полноценную эксплуатацию спустя короткое время после начала его разработки.
Метафора
   Вы не можете приступать к разработке, обладая лишь метафорой. В метафоре недостаточно детально отображено строение системы, кроме того, что, если, формируя метафору, вы сделаете ошибку?
   Однако в ХР:
   • вы обладаете быстрой и надежной обратной связью, благодаря чему вы на основании реального кода и тестов узнаете о том, работает ли метафора на практике;
   • вашему заказчику очень удобно разговаривать о системе в терминах метафоры;
   • вы выполняете переработку (refactor) для того, чтобы постоянно пересматривать ваше представление о том, что метафора означает на практике.
   При выполнении этих условий вы, скорее всего, можете без опасений приступать к разработке, обладая лишь метафорой.
Простой дизайн
   Вы не можете разрабатывать систему, дизайн которой достаточен лишь для того, чтобы решать только сегодняшние задачи. Вы не можете проектировать систему, не уделяя внимание тому, с какими проблемами вам придется столкнуться завтра. Используя предлагаемый в ХР подход, вы можете загнать себя в угол, при этом вы потеряете возможность дальнейшего эволюционирования системы.
   Однако в ХР:
   • вы привыкаете к постоянной переработке кода, благодаря чему внесение в дизайн системы не представляет для вас сложностей;
   • вы обладаете понятной всеобщей метафорой, благодаря чему вы можете быть уверенными в том, что любые изменения в дизайне будут выполняться в рамках единого пути, сходящегося в одной точке;
   • вы программируете не один, а с партнером, поэтому вы можете быть уверенными в том, что вы формируете простой дизайн, а не глупый дизайн.
   • вы используете простой дизайн, поэтому переработка кода выполняется проще;
   • у вас есть тесты, поэтому вряд ли вы нарушите целостность кода, не узнав об этом сразу же;
   • вы постоянно выполняете интеграцию системы, поэтому если вы нечаянно нарушите что-либо в системе или выполненная вами переработка конфликтует с чьей-либо работой, вы узнаете об этом в течение ближайших нескольких часов;
   • вы полноценно отдыхаете после работы, поэтому у вас достаточно сил и храбрости для выполнения переработки, кроме того, вы реже совершаете ошибки.
   При выполнении этих условий вы, скорее всего, можете без опасений перерабатывать код тогда, когда вы видите в этом необходимость. Необходимость в переработке возникает тогда, когда вы хотите сделать систему проще, устранить дублирование кода или обеспечить лучшую коммуникацию.
Программирование в парах
   Вы не можете программировать парами. Двум людям очень сложно писать один и тот же код. Это слишком медленно. Кроме того, вам кажется, что два человека по отдельности на двух разных компьютерах напишут в два раза больше кода, чем вместе на одном компьютере.
   Однако в ХР:
   • стандарты кодирования снижают трения между членами пары;
   • каждый из членов пары полноценно отдыхает, поэтому снижается вероятность бесполезных... э-э-э... дискуссий;
   • программисты в парах разрабатывают тесты совместно, поэтому перед тем, как переходить к реализации, они сначала согласуют между собой свои представления о решении стоящей перед ними задачи;
   • пары используют метафору для формирования таких решений, как именование элементов системы и базовый дизайн;
   • пары работают в рамках простого дизайна, поэтому оба программиста в паре без затруднений понимают, что, собственно, происходит.
   При выполнении этих условий вы, скорее всего, можете писать весь код приложения в парах вплоть до внедрения этого приложения в реальных производственных условиях. Мало того, если люди программируют в одиночестве, они с большей вероятностью совершают ошибки, они зачастую чрезмерно усложняют дизайн и действуют с нарушением других принятых методик работы (часто это происходит под внешним давлением).
Коллективное владение
   Вы не можете разрешить каждому члену команды вносить любые изменения в любое место системы в любое удобное для этого время. В результате этого программисты немедленно разбросают код направо и налево и стоимость интеграции стремительно вырастет.
   Однако в ХР:
   • интеграция выполняется очень часто, каждые несколько часов, поэтому вероятность конфликтов снижается;
   • вы пишете и постоянно запускаете тесты, поэтому вероятность нарушения работы системы снижается;
   • вы программируете в парах, поэтому вероятность ошибок снижается и программисты понимают код быстрее, чем могут его изменить;
   • вы действуете в рамках стандартов кодирования, поэтому конфликты стиля не возникают, а код становится понятным каждому члену команды (например, ситуация, когда разные люди привыкли ставить фигурные скобки по-разному, называется Curly Brace Wars – война фигурных скобок).
   При выполнении этих условий вы, скорее всего, можете без опасений разрешить каждому члену команды изменять код в любой части системы тогда, когда ему это надо, и так, как он считает нужным для того, чтобы улучшить его. Мало того, если не использовать модель коллективного владения кодом, скорость эволюционирования дизайна значительно понижается, а это не идет на пользу системе.
Постоянно продолжающаяся интеграция
   Вы не можете интегрировать всю систему каждые несколько часов работы. Интеграция – это очень серьезный и длительный процесс, в ходе которого, как правило, приходится устранять множество конфликтов, при этом может нарушиться целостность кода.
   Однако в ХР:
   • вы можете запустить тесты и быстро убедиться в том, что все работает;
   • вы программируете парами, поэтому у вас наполовину меньше источников кода, которые требуется интегрировать и согласовывать между собой;
   • вы выполняете переработку кода, и в процессе этого устраняется значительная часть конфликтов.
   При выполнении этих условий вы, скорее всего, можете выполнять интеграцию каждые несколько часов. Мало того, если вы не выполняете интеграцию с достаточной частотой, вероятность возникновения конфликтов, равно как и стоимость интеграции, стремительно растет.
40-часовая рабочая неделя
   Вы не можете работать только 40 часов в неделю. Вы не успеете выполнить весь необходимый объем работ.
   Однако в ХР:
   • игра в планирование заставляет вас делать наиболее важную работу в первую очередь;
   • комбинация игры в планирование и тестирования снижает вероятность возникновения неприятных сюрпризов (именно такие сюрпризы являются причиной того, что приходится работать сверхурочно);
   • весь набор рассматриваемых методик помогает вам программировать с максимальной скоростью, поэтому вы все равно не сможете сделать запланированный на неделю объем работ быстрее.
   При выполнении этих условий вы, скорее всего, выполните весь запланированный на неделю объем работ в течение 40-часовой рабочей недели. Мало того, если команда не получит полноценного отдыха, люди будут сильно уставать и не смогут придерживаться всех остальных методик.
Заказчик на месте разработки
   Вы не можете получить реального представителя заказчика, который все свое рабочее время сидел бы в офисе, где осуществляется разработка. Такой человек более ценен на производстве – там он приносит больше пользы для бизнеса.
   Однако в ХР:
   • представитель заказчика приносит пользу для проекта, так как он пишет функциональные тесты (предприятию-заказчику все равно придется этим заниматься);
   • представитель заказчика приносит пользу проекту, устанавливая мелкомасштабные приоритеты и участвуя в принятии некоторых важных решений для программистов.
   При выполнении этих условий представители заказчика смогут быть более полезными для компании благодаря тому, что они вкладывают свои усилия в разработку проекта. Мало того, если в состав команды не включить представителя заказчика, риск, связанный с проектом, увеличивается, так как программисты пытаются заранее предугадать, с какими задачами им придется иметь дело в будущем, они вынуждены заранее планировать структуру системы и кодировать, не зная при этом, какие тесты им придется удовлетворить, а какие тесты им разрешается игнорировать.
Стандарты кодирования
   Вы не можете заставить команду кодировать в соответствии с общими для всех стандартами. Каждый программист – это индивидуальность, ему легче отказаться от общих стандартов, чем подчиниться требованию ставить фигурные скобки так, как делают это остальные члены команды.
   Однако в ХР:
   • Вся дисциплина ХР способствует тому, что программисты в большей степени чувствуют себя членами команды, которая побеждает.
   При выполнении этого условия входящие в команду программисты с большей охотой поправят свой стиль. Мало того, без использования стандартов кодирования дополнительные трения станут причиной значительного замедления программирования в парах и переработки кода.
Заключение
   Любая из рассмотренных методик сама по себе плохо приспособлена для использования в рамках программистского проекта (за исключением, возможно, тестирования). Чтобы обеспечить их эффективное применение на практике, вы должны использовать их все одновременно. На рис. 4 изображена диаграмма, которая иллюстрирует взаимодействие всех методик.
   Линия между двумя практиками указывает на то, что обе эти практики являются поддержкой друг для друга. Я не хотел размещать этот рисунок в самом начале главы, так как при взгляде на него вы могли решить, что ХР – это слишком сложная штука. Отдельные части сами по себе очень просты. Насыщенность и богатство происходят от взаимодействия между составными частями этой дисциплины.