Алистэр Коуберн
 
Парное программирование: преимущества и недостатки

   Humans and Technology 7691 Dell Rd Salt Lake City, UT 84121, USA
 
    arc@acm.org801.947.9277
 
   Лори Вильямс University of Utah Computer Science 50 S. Central Campus #3190 Salt Lake City, UT 84112, USA
 
    lwilliam@cs.utah.edu435.649.7931
   Original text at: http://members.aol.com/humansandt/papers/pairprogrammingcostbene/pairprogrammingcostbene.htm
   "Только в том случае, когда различные элементы - имена, определения, намеки и ощущения - тщательно проверяются и подгоняются друг к другу, причем доброжелательно, без неприязни во время обсуждения, только тогда воссияют понимание и здравомыслие - наивысшая цель, которую может поставить перед собой человек…" - Платон

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

 

Введение

   При парном программировании разработчики решают все задачи совместными усилиями, работая бок о бок за одним компьютером. За последние несколько десятков лет такая практика уже неоднократно получала самые лестные отзывы, так как с ее помощью удавалось значительно улучшить процесс разработки ПО.
   Однако существует мнение, сводящее на нет любые доводы в пользу парного программирования - многие полагают, что посадить двух программистов за один компьютер, значит поручить двум разработчикам работу одного.
   С точки зрения руководителя, программист - слишком ценный ресурс, поэтому он не желает тратить его понапрасну, удваивая количество людей, необходимых для разработки той или иной задачи.
   Программисты привыкли считать свою работу индивидуальным, а не коллективным трудом (это убеждение основано как на навыках, которые они получали в процессе обучения, так и на опыте работы).
   Многие опытные программисты отказываются работать в паре. Некоторые мотивируют это тем, что их код "слишком индивидуален", другие утверждают, что напарник будет тормозить их работу, третьи говорят, что в таком случае будет очень трудно координировать рабочее время или версии кода.
   И в то же время:
   Довольно много известных и уважаемых программистов предпочитают парное программирование любому другому стилю работы.
   Те программисты, которые уже привыкли к "парному" стилю работы, говорят, что так работается "как минимум, вдвое быстрее".
   Что касается качества программы, то опыт показывает, что при парном программировании система имеет лучший дизайн и более простой код, который в будущем можно легко расширять и модифицировать.
   Согласно опросам, даже новички-программисты, работающие в паре с опытным специалистом, вносят в его код много полезных дополнений.
   Все это поднимает несколько довольно провокационных вопросов. Действительно ли парное программирование эффективнее одиночного? Что оно представляет собой в экономическом плане? И, наконец, нравится ли людям работать в паре? Не теряют ли они удовольствие от работы?
   Основываясь на растущем интересе к парному программированию, авторы данной статьи провели несколько опросов и экспериментов, чтобы собрать материал, по которому можно было бы судить об издержках и выгодах, которые несет с собой эта практика. В этой статье мы приводим результаты этого исследования. В прежних публикациях уже говорилось, что парное программирование положительно сказывается на процессе разработки ПО. Цель нашей статьи - перепроверить результаты прежних исследований в этой области и более подробно объяснить, чем же выгодно парное программирование.

Пример использования парного программирования в одном из проектов

   Ниже мы приводим цитату из рассказа опытного программиста о том, как его компания впервые попробовала использовать парное программирование. В этом примере упомянуто много основных черт парного программирования, которые мы рассмотрим в этой статье более подробно.
   В начале декабря моя команда занялась довольно рискованной деятельностью. Эта деятельность включала в себя внесение изменений практически в каждый файл и слияние фрагментов кода. При всем при этом надо было ничего не сломать. Дальше больше - в архитектуру одной из подсистем потребовалось внести довольно существенные изменения. Итак, с одной стороны, эта работа представляла собой скучнейшую рутину, а с другой - требовала постоянного внимания и напряженной работы мысли.
   Разработчики согласились со мной в том, что парное программирование:
   - Должно существенно уменьшить риск появления скрытых ошибок, а значит сделать отладку программы менее мучительным процессом;
   - Даст нам возможность провести гораздо более полную проверку кода, чем мы когда-либо делали; а кроме того
   - Предоставит программистам возможность обмениваться знаниями.
   Первые несколько недель работа шла совсем не так, как мы того ожидали. Вместо парного программирования люди начали работать в режиме, который я называю "партнерским программированием". Каждый сам писал свой код, а потом проверял его вместе со своим партнером перед внесением изменений в общий репозиторий. По их словам, благодаря этому они стали находить ошибки на ранних стадиях работы. Звучало обнадеживающе, но я все равно был разочарован тем, что они не работают все время вместе.
   Приблизительно через четыре месяца я стал замечать некоторые изменения. Одна пара разработчиков весь день работала всместе - это было настоящее парное программирование. Другие две пары тоже были близки к этому идеалу. В процессе обсуждения стало ясно, почему изменения в процессе все-таки произошли. Так было удобнее работать!
   Программисты обнаружили, что работать независимо, а потом проверять код занимает больше времени, поскольку в процессе проверки приходится обучать партнера всему тому, что узнал сам, пока вносил изменения. Обучение это отнимало почти столько же времени, сколько уходило на внесение изменений. Когда программисты работали вдвоем, им не нужно было делать "двойную работу", процесс кодирования шел быстрее благодаря известному принципу "одна голова хорошо, а две лучше", и разработчики были значительно более уверены в качестве конечного результата.
   Наконец, мы подготовили промежуточную версию системы и отдали ее в отдел контроля качества (QA). К нашему удивлению, процесс тестирования прошел без сучка без задоринки. Это было тем более удивительно, что одну из подсистем некоторое время назад целых шесть (!) недель мучили в отделе QA. Было совершенно очевидно, что парное программирование коренным образом уменьшило количество дефектов в системе.
   С течением времени сотрудничество программистов становилось все более тесным.
   … Когда работа над каждой из подсистем заканчивалась, пары перегруппировывались, в зависимости от навыков, требуемых для решения следующей задачи. Это несколько замедляло работу, так как новым парам требовалось время, чтобы сработаться, прежде чем они начинали трудиться с прежней эффективностью. К августу пары сработались уже настолько, что один из партнеров мог запросто выражать их общее мнение на собраниях, проходивших у нас два раза в неделю.
   Последующие релизы, как внутренние, так и внешние, проходили достаточно гладко. критические ошибки обнаружиливались в системе исключительно редко. Благодаря непрерывной проверке кода мы выявили большую часть серьезных проблем, в том числе незамеченные ранее существенные недоработки в дизайне системы.
   Сам я начал работать в паре только к концу проекта. Как только моему партнеру и мне удалось синхронизировать наши мысли, я понял, как замечательно работать вдвоем.
   И хотя ему не хватало опыта, он умел так сформулировать вопрос, что подыскивая ответ, мы, как правило, находили оптимальное решение для каждой проблемы.
   … После этого разработчики сами решили использовать практику парного программирования и в дальнейшем. Никакие указания свыше не сравнятся с личным опытом.

Направления исследования

   Мы рассмотрим здесь восемь направлений исследования, связанных с программированием и организационной эффективностью. Удивительно, но все они свидетельствуют в пользу парного программирования. Итак, мы вели наши исследовали в следующих направлениях:
    Экономическая обоснованность.Недавние эксперименты показали, что стоимость разработок при добавлении второго программиста возрастает совсем немного. Однако в этом случае программный код будет иметь гораздо меньше дефектов. Таким образом, изначальные затраты с лихвой компенсируются экономией на исправлении ошибок.
    Удовлетворение от работы.Те разработчики, которые пробовали программировать вдвоем, считают, что так работать гораздо приятнее, чем в одиночку.
    Качество дизайна системы.Исследования показали, что программисты, работавшие попарно, выпускали более короткие программы, нежели их коллеги, которые работали в одиночку (а как известно, чем короче программа, тем лучше ее дизайн). Об этом же свидетельствуют и личные впечатления разработчиков.
    Непрерывность проверки кода. При парном программировании происходит постоянная проверка как кода, так и дизайна системы, что ведет к существенному снижению коэффициента ошибок.
    Решение проблем.Все опрошенные нами программисты подчеркивали, что при парном программировании возрастает способность команды быстро находить выход в "безвыходных" ситуациях.
    Обучение.Работающие в парах программисты утверждают, что многому учатся друг у друга. .
    Формирование команды и коммуникации.Опрошенные нами программисты говорят, что с помощью парного программирования разработчики в их командах учатся обсуждать проблемы и решать их совместными усилиями. Это улучшает и качество общения людей, и эффективность их работы.
    Персонал и управление проектом. Когда каждый фрагмент кода хорошо знаком не одному разработчику, а сразу многим, это снижает риск, связанный с изменениями в персонале компании.
   Далее мы рассмотрим каждый из восьми пунктов более подробно, с привлечением статистических данных и информации, полученной в результате многочисленных опросов и интервью. Все это позволит более точно определить затраты, которые требует парное программирование, и выгоды, которые оно приносит.

Экономическая обоснованность

   Ключевой вопрос, возникающий при обсуждении целесообразности перехода на парное программирование - это затраты, которых оно потребует. Если методика требует слишком больших расходов, то никакой руководитель компании просто не станет ее вводить. Скептики полагают, что переход на парное программирование влечет за собой удвоение расходов на разработку программы и персонал. Однако, помимо этих затрат существуют и другие виды расходов, которые тоже необходимо учитывать: контроль качества и поддержка уже находящегося в эксплуатации продукта. Так, IBM сообщает, что они потратили около 250 миллионов долларов только на устранение 30 000 проблем, о которых заявили их клиенты. Итого, по 8 000 долларов за каждую ошибку!
   В 1999 году второй автор этой статьи (Лори Вильямс) провел в университете Юта эксперимент по выяснению экономических аспектов парного программирования. В нем участвовали студенты старших курсов, обучавшихся по специальности "Software Engineering". Треть группы писала программы обычным способом - то есть, в одиночку. Остальные работали над проектом в паре с партнером. На рисунке 1 вы видите, сколько времени затратили на выполнение заданий первая и вторая группы студентов. После начального периода "притирки" партнеров, которая проходила во время работы над первой программой, пары программистов тратили всего на 15% больше времени, чем индивидуалы. Как видите, парное программирование отнюдь не удваивает стоимость разработки!
   Рисунок 1: Время, затраченное на выполнение контрольных заданий
   Важно отметить, что получившийся в результате парного программирования код содержал на 15% меньше ошибок, чем код индивидуалов. (Эти результаты подтверждены статистикой.) На рисунке 2 показано, с каким успехом проходили тестирование программы, написанные студентами обеих групп (иными словами, процент успешно пройденных тестов, которые писал инструктор).
   Рисунок 2: Ошибки в программах
   Изначальное 15% увеличение стоимости разработки окупается за счет уменьшения количества ошибок. Проиллюстрируем это положение наглядным примером. Предположим, что программа в 50 000 строк кода (50 000 LOC) разрабатывается группой программистов-"одиночек" и группой программистов, работающих в парах. При типичной скорости разработки 50 LOC в час "одиночки" напишут эту программу за 1000 часов. "Пары" затратят на ту же задачу на 15% больше, то есть 1150 часов. Таким образом, стоимость разработки вырастает на 150 часов. Основываясь на статистических данных, программист совершает 100 ошибок на 1000 строк кода. Правильно поставленный процесс разработки позволяет выявить около 70% этих ошибок. Следовательно, у "одиночек" в программе останется порядка 1500 ошибок, в то время как у "пар" их будет на 15% (на 225) меньше - 1275 ошибок.
   В некоторых компаниях программный код передается в отдел тестирования или контроля качества, который находит и исправляет существенную часть оставшихся в программе ошибок. Обычно при проведении системных тестов на одну ошибку уходит от четырех до шестнадцати часов. Возьмем нечто среднее - 10 часов, тогда получится, что на исправление этих "лишних" 225 ошибок отдел тестирования потратит около 2250 часов. А это в 15 раз больше, чем изначальное увеличение затрат на парное программирование - 150 часов!
   Если же по окончанию работ программа отправляется непосредственно заказчику, то парное программирование оказывается еще более выгодным. По данным статистики, после выхода программы в эксплуатацию на исправление одной ошибки уходит от 33 до 88 часов. Возьмем оптимистичный вариант - по 40 часов на ошибку, тогда если клиет обнаружит 225 дополнительных ошибок, это будет стоить компании-разработчику 9 000 часов - в 60 раз больше, чем те затраты, которые требовались при использовании парного программирования!
   Таким образом, даже если судить только с экономической точки зрения, парное программирование вполне себя оправдывает. Впрочем, есть и другие аспекты, на которые стоит обратить внимание.

Удовлетворение от работы

   Если парное программирование не будет доставлять удовольствие, то программисты не будут его использовать.
   Изначально многие разработчики настроены по отношению к парному программированию скептически, даже враждебно. Дело в том, что работа с партнером меняет условия работы программиста-одиночки, к которым он так привык. Один программист написал:
   "Перестроиться с одиночного программирования на парное - все равно, что приучить себя к острой пище. Когда вы в первый раз пробуете ее, она кажется совершенно отвратительной, потому что вы просто к ней не привыкли. Но чем больше вы будете есть острого, тем вкуснее оно вам покажется."
   Согласно статистике, программисты, которые ранее работали в одиночку, а теперь работают в парах, считают, что им больше нравится новый способ работы. Одной из причин они называют возросшую уверенность в качестве своего кода (коэффицент ошибок в том и другом случае подтверждает последнее замечание). На рисунке 3 вы видите результаты анонимного исследования, проведенного в университете Юта среди профессиональных программистов и студентов. Как видите, большинству программистов совместный стиль работы нравится больше.
   Рисунок 3: Удовлетворение от работы
   Как заметил один из программистов,
   "С психологической точки зрения, очень приятно осознавать, что в твоей программе нет серьезных ошибок… Я чувствую себя гораздо увереннее, когда мой партнер просматривает весь код, который я пишу. В этом случае, я могу быть уверен, что делаю свою работу хорошо, ведь ее проверяет и одобряет человек, с которым я работаю и кому доверяю."
   На эту тему есть еще один замечательный комментарий :
   "Так здорово вместе радоваться, когда что-то работает."
    Студенты предпочитают иметь 15%-ные издержки//работать больше, но с партнером
   Мы уже рассказывали, что для предыдущего эксперимента поделили всю группу студентов на две части: группу "индивидуалов", в которой каждый писал код в одиночку, и группу "коллективистов", где все программисты работали попарно. Каждое задание состояло из одной программы для "индивидуалов" и двух - для "коллективистов".
   После выполнения нескольких заданий двое программистов, работавших в паре, стали жаловаться, что дескать, задания назначаются несправедливо: "парам" приходится работать больше, чем "одиночкам". Инструктор тут же предложил этим студентам перейти в группу "индивидуалов" и работать по одному, но оба даже слышать об этом не хотели. Больше никаких жалоб на "несправедливость" от них не поступало.
   Нам кажется, что такое поведение свидетельствует о том, что разработчикам нравится работать вдвоем.

Качество дизайна системы

   Ниже мы приводим слова руководителя одной из команд разработчиков, который и слыхом не слыхал о парном программировании. Здесь он объясняет, почему все его проектировщики-программисты работают вместе за одним терминалом.
   Во время работы над проектом я заметил, что одна из наших команд всегда разрабатывает дизайн более высокого качества. Я спросил у ребят, как это им удается.
   Они сказали, что это происходит потому, что они стали работать вместе - как над дизайном программы, так и над его реализацией в коде. В результате, и дизайн, и код становятся лучше. Я согласился с ними и перевел все остальные команды на тот же стиль работы. Теперь качество дизайна стало намного лучше.
   [из архивов Алистэра Коуберна]
   В 1991 году Ник Флор (Nick Flor), занимавшийся в то время когнитологией (Cognitive Science), сделал интересный вывод о распределенности знаний у программистов, работавших в паре, которых он изучал. Распределенное знание - это один из разделов когнитологии, основное положение которого можно выразить словами: "Все, кому приходилось изучать процесс осмысления, были поражены тем фактом, что "разум" очень редко работает в одиночку. Вся данные, которые человек поднимает во время этого процесса, оказываются распределенными - по различным умам, людям, а также символическому и физическому окружению, в котором этот человек находится."
   С помощью видео и аудио аппаратуры Флор фиксировал все виды обмена мнениями между двумя программистами, которые работали над одной задачей. В этом исследовании Флор установил соотношения между вербальным и невербальным поведением программистов. Для этого он использовал известные когнитологические теории, касающиеся распределенного знания. Одна из таких теорий - "Поиск в более обширном пространстве возможностей" ("Searching Through Larger Spaces of Alternatives.")
   "С точки зрения генерации разнообразных планов, система со многими действующими лицами обладает большим потенциалом. Можно назвать, по крайней мере, три причины: во-первых, все действующие лица привносят в разработку свой уникальный личный опыт; во-вторых, каждый из них обладает своим подходом к информации, касающейся выполняемой задачи; в-третьих, все они находятся в разных отношениях к проблеме, поскольку выполняют разные функциональные роли… Главным следствием попытки свести воедино все имеющиеся цели и планы является то, что в такой конфликтной, по сути, ситуации программисты должны открыто договориться, какую последовательность действий необходимо будет предпринять. Вырабатывая, таким образом, единое общее решение, они перебирают гораздо большее количество альтернативных вариантов, чем мог бы в такой ситуации программист-одиночка. Именно это обстоятельство и ведет к снижению риска выбора плохого плана действий."
   Посмотрите, что говорит программист, работающий в паре с партнером, и как это совпадает с тем, что мы прочли у Флора:
   Часто все мы имели разные идеи относительно того, как должен выглядеть дизайн системы. Как правило, пока мы спорили, какой из вариантов лучше, мы действительно приходили к самому лучшему решению, которое являлось гибридом всех предложенных вначале.
   Во время количественных исследований, проведенных в университете Юта, работающие попарно программисты не только разрабатывали программы высокого качества, но и реализовывали необходимую функциональность в меньшем количестве строк кода, чем программисты-одиночки. Более подробно эти данные представлены на рисунке 4. Нам кажется, что краткость программного кода свидетельствует о более качественном дизайне всей системы.
   Рисунок 4: Количество строк кода

Непрерывность проверки кода

   Уже двадцать лет тому назад было установлено, что визуальная проверка кода - это эффективный, с точки зрения стоимости, метод исправления дефектов в программных продуктах. Это подтверждают и эмпирическими исследованиями, однако несмотря на это, большинство программистов не любят проверок и не считают это занятие ни приятным, ни стоящим. В результате о проверках, как правило, забывают (за исключением тех случаев, когда их выполнение требуется официально). Зачастую проверку кода осуществляют неподготовленные к этой задаче программисты.
   "Несмотря на положительные результаты исследований в течение более 20 лет, процедура проверки кода очень плохо приживается в индустрии производства программных продуктов. Точных данных у нас нет, однако согласно неформальному обзору USENET-групп, 72 из 90 опрошенных программистов практикуют проверку кода крайне редко, или вообще ей не занимаются."
   Идея проверки кода базируется на известном постулате: чем раньше обнаружен дефект, тем проще и дешевле его исправить. Существует много исследований на эту тему, в некоторых даже утверждается, что исправление дефекта будет стоить в десять раз дороже на каждой последующей ступени развития проекта.
   Экспоненциальный рост стоимости дефектов легко объяснить. Во время проверки, программист говорит: "У оператора "if", что на 450 строке кода, должен быть оператор "else"." После этого ему понадобится несколько минут, чтобы быстро исправить эту ошибку на своем компьютере. Если же программный продукт уже находится в эксплуатации, то в один прекрасный день раздается звонок разъяренного клиента: "Новый год на носу, а у меня ни одна касса не работает! Я ни-че-го не могу продать! Вы меня разоряете!"
   Итак, в первом случае программист имеет дело с ошибкой, на которую ему только что указали. Во втором случае, группа технической поддержки должна потратить время на диагностику проблемы (все кассовые аппараты не работают), затем обратиться к самой системе и определить, где нужно вносить исправления (в какой строке кода не хватает оператора "else"). На этом примере всякий может убедиться - работа группы поддержки, которой надо проанализировать проблему и выявить дефект, стоит гораздо дороже, чем те несколько минут, которые должен затратить программист на исправлении ошибки в своем собственном коде. Если программисты работают парами, то такие проверки кода происходят непрерывно. А непрерыная проверка кода не только опережает спорадические "инспекции" как по качеству, так и по скорости нахождения ошибок, но и не вызывает у программистов отрицательных эмоций.
   Посмотрите, как сардонически описывает свой опыт программирования в паре с новичком опытный программист, который в начале был настроен к идее совместной работы весьма скептически. К своему удивлению, этот специалист вдруг обнаруживает, что даже новичок может существенно улучшить качество кода, который он пишет.
   Как-то я работал с одним из наименее опытных разработчиков над довольно простой задачей. Честно говоря, я всегда считал себя замечательным специалистом по языку Smalltalk, поэтому был уверен, что просто буду учить молодежь, как надо работать.
   Не прошло и нескольких минут, как этот малец задает мне вопрос - почему, дескать, я делаю то, что я делаю. И точно, оказалось, что я уже совершил ошибку! Я исправился. Тогда этот бойкий мальчишка напомнил мне правильное название метода или чего-то там еще, что я писал в тот момент неправильно. Вскоре он уже вовсю указывал мне, что я должен делать дальше, а сам успевал подмечать еще и все ошибки в синтаксисе и форматировании.
   [со слов Рона Джеффриза]
   И наконец, еще одним преимуществом постоянных проверок кода является то, что с их помощью разработчики узнают новые способы и стили кодирования, особенности языка и лучше представляют себе всю систему.
   Непрерывная проверка кода при совместном программировании создает уникальные условия для обучения, поскольку оба программиста постоянно учатся друг у друга. "Проверка кода - это уникальная возможность для обучения: процесс анализа и критики программных артефактов, которые создал кто-то другой, представляет собой замечательный по эффективности способ изучения языков, техники проектирования, предметной области и т.д."