Чистый Agile. Основы гибкости — страница 21 из 36

Шел 1995 год. На следующий день была запланирована к выходу из печати моя первая книга, и мне кровь из носу нужно было представить корректуру. Было 6 утра, у меня уже все было на руках. Надо было просто залить файл на FTP-сервер издателя.

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

Мы посмотрели друг на друга и тяжело вздохнули. Джим сказал: «Нужно все переделывать». Это был не вопрос. Это была констатация факта. Все трое посмотрели друг на друга, потом на часы. Потом снова друг на друга. А потом пошли горбатиться.

Но когда мы все сделали, посиделки закончились. Мы отправили книгу. И пошли спать.


Сон

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

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

В проекте, где применяется Agile, у кода нет владельца. Код — это коллективное владение команды как единого целого. Любой член команды в любое время имеет право проверить и усовершенствовать любой модуль проекта. Команда коллективно располагает всем кодом.

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

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

У центрального компьютера и периферийных были совершенно разные архитектуры. Один был такой же, как PDP-8, только его слово составляло 18 бит. У него было 256 килобайт оперативной памяти, а данные загружались с кассеты с магнитной лентой. Другой имел 8-битный микропроцессор 8085 с 32 килобайтами оперативной памяти и 32 килобайтами постоянной памяти.

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

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

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

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

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


Секретные материалы

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

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

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

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

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

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

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

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

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

В первые дни существования Agile метод «непрерывная интеграция» означал, что разработчики отмечали изменения в своем исходном коде и объединяли их с основной веткой каждые «пару часов»[47]. Все модульные и приемочные тесты проходили успешно. Не оставалось веток, которые бы не были объединены. Все ненужные при развертывании изменения отключались с помощью тумблера.

В 2000 году на одном из уроков на курсах XP Immersion один студент угодил в классическую ловушку. Эти уроки были очень насыщенны. Мы сократили циклы так, что итерации составляли всего один день. Цикл непрерывной интеграции составлял лишь от четверти до получаса.

Один студент работал в команде из шести разработчиков, пятеро из которых отмечали изменения чаще, чем он. Непонятно почему, он был без пары. И вышло так, что он не выполнял слияние кода более часа.

Когда он наконец решил отметить изменения и выполнить слияние кода, он увидел, что накопилось столько изменений, внесенных другими студентами, что ему пришлось хорошенько повозиться, чтобы объединить код. Пока он копался и выполнял слияние, остальные программисты продолжали отмечать изменения каждые 15 минут. И когда он наконец разобрался и попробовал отметить изменения в своем коде, то увидел, что снова попал впросак.

Он так расстроился, что встал посреди кабинета и громко провозгласил: «Ваше экстремальное программирование — полная ерунда!» После этого он вылетел из класса и направился в бар гостиницы.

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

Мораль: метод «непрерывная интеграция» работает только тогда, когда интеграция действительно непрерывна.


А вот и непрерывная сборка

В 2001-м Thought Works значительно изменили положение дел. Они создали CruiseControl[48], первое средство непрерывной сборки. Я помню, как в 2001-м на XP Immersion Майк Ту[49] читал ночную лекцию об этом. Не сохранилось записи этой лекции, но история была примерно таковой:

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