Чистый Agile. Основы гибкости Мартин Роберт
Это своего рода благоприятный этап проекта. Все спокойно просматривают страницы в интернете, проводят небольшие сделки, встречаются с клиентами и пользователями, рисуют красивые графики, попросту говоря, весело проводят время.
Затем первого июля происходит чудо. Анализ завершен.
А почему мы так считаем? Потому что уже первое июля. Если по графику этап анализа должен завершиться первого июля, значит, что первого июля этот этап завершен. Мы ведь не опоздали? Поэтому устроим небольшую вечеринку с воздушными шарами и пламенными речами, отпразднуем наш переход от этапа анализа к этапу проектирования.
Этап проектирования
А что теперь делать? Конечно же, будем проектировать. Но что представляет собой проектирование?
Об этапе проектирования программного обеспечения нам известно чуть больше. На этом этапе мы разбиваем проект на отдельные модули и проектируем интерфейсы между этими модулями. На этом этапе мы также предполагаем, сколько команд нам понадобится и как эти команды будут связаны между собой. В общем, нужно уточнить график работ, чтобы составить правдоподобный осуществимый план по реализации.
Безусловно, на этом этапе что-то неожиданно меняется. Добавляются новые функции. Старые функции исчезают или корректируются. И было бы неплохо оглянуться назад и провести анализ изменений заново, но время — деньги. Поэтому мы всеми возможными способами стараемся внести изменения в проектирование.
И тогда случается новое чудо. Первого сентября мы внезапно завершаем проектирование. А почему так? Да потому что. Первое сентября. По графику работ мы должны были уже закончить. Незачем медлить.
Итак, еще одна вечеринка. Воздушные шары и речи. И мы прорываемся к следующему этапу — реализации.
Было бы замечательно провернуть такую схему еще разок. Эх, если бы точно так же можно было бы завершить этап реализации! Но так уже не выйдет. Потому что по завершении реализации требуется завершить и весь проект. Анализ и проектирование не приносят плодов в двоичном виде. У них нет однозначных критериев завершенности.
Нет объективного способа узнать, проведены ли они в реальности. Поэтому и получилось завершить эти этапы вовремя.
Этап реализации
А вот у реализации как раз есть отчетливые критерии завершенности. Тут уже не получится аккуратно схалтурить, выдав мнимый результат за действительный[23].
На этапе реализации полностью отсутствует двусмысленность задач. Мы просто пишем код. И нам приходится писать код второпях, высунув язык, потому что четыре месяца просто выкинули на ветер.
Между тем требования к проекту продолжают меняться. Добавляются новые функции. Старые функции исчезают или корректируются. Нам бы вернуться назад, провести новый анализ и внести изменения в проектирование, но… осталось лишь две недели. И ударными темпами мы вбиваем все эти изменения в код.
По мере того как мы смотрим на код и сравниваем его с результатом проектирования, мы осознаём, что, должно быть, были не в себе на этапе проектирования, потому что сам код имеет мало общего с тем, что было изначально изображено на замечательных графиках. Но времени на раздумья нет, потому что часики тикают, а сверхурочной работы становится все больше.
Примерно 15 октября кто-то говорит: «Эй, а какое сегодня число? Когда сдавать?» И тут мы понимаем, что осталось всего две недели и к первому ноября мы ни за что не закончим. И вдруг впервые наши заказчики узнают, что с проектом возникают какие-то неувязочки.
Представьте их негодование. «А на этапе анализа нельзя было об этом сказать? Разве не тогда вы должны были оценить размер проекта и внимательно рассчитать график работ? А на этапе проектирования почему не сказали? Разве не тогда нужно было разбить проект на модули, распределить работу по всей команде и рассчитать человеческий ресурс? Почему мы узнаем обо всем за две недели до дедлайна?»
И ведь они правы, разве нет?
Марафон на выживание
И начинается марафон на выживание. Клиенты злятся. Заинтересованные стороны дошли до белого каления. Давление нарастает. Работаем сверхурочно. Кто-то уходит с проекта. Просто ад!
И уже где-то в марте мы с горем пополам выдаем результат, который лишь наполовину удовлетворяет требованиям клиентов. Все расстроены. У всех опускаются руки. И мы клянемся самим себе, что в следующий раз такого не произойдет. В следующий раз мы все сделаем по уму. В следующий раз анализ и проектирование будут выполнены на совесть.
Я называю это раздуванием вышедшего из-под контроля процесса. Мы собираемся в следующий раз еще лучше работать по методу, который не работает.
Преувеличение?
Очевидно, что история утрирована. В ней собрано воедино все отрицательное, что вообще может быть во время работы над проектом по разработке программ. Большинство проектов, где применялась каскадная модель, не терпели такого краха. Действительно, по счастливой случайности некоторые проекты удавалось завершить даже относительно успешно. С другой стороны, на подобной встрече я бывал не раз, мне доводилось работать не над одним таким проектом, и такое случалось не только со мной. История гиперболизированная, но такое все равно бывает.
Если меня спросить, сколько проектов, разработанных по каскадной модели, провалились с таким же треском, как в описанной выше истории, я отвечу, что сравнительно мало. С другой стороны, это больше, чем ничего, что тоже плохо. Кроме того, большая часть таких проектов испытывала подобные трудности в большей или меньшей степени.
Каскадная модель не самая ужасная из того, что существует. Не все проекты, выполняемые по ней, разлетались в прах. Но она как была, так и остается плачевным способом ведения проекта.
Способ получше
Проблема в том, что каскадная модель кажется очень понятной. Сначала мы проводим анализ задачи, потом проектируем решение и уже потом осуществляем реализацию.
Просто. Доступно. Очевидно. И неправильно.
Подход, предлагаемый Agile, в корне отличается от того, что было написано выше, но при этом так же понятен. По мере прочтения, полагаю, вы увидите, что в нем гораздо больше смысла, чем в трех словах, описывающих каскадную модель.
Проект по Agile начинается с анализа, однако анализ сопровождает весь цикл разработки. На рис. 1.4 изображена схема, объясняющая принцип ведения проекта в целом. Справа — дата сдачи проекта, 1 ноября. Помните, первое, что надо знать, — это срок сдачи. Срок требуется поделить на закономерные интервалы, называемые итерациями, или спринтами[24].
Длительность одной итерации, как правило, составляет одну или две недели. Я предпочитаю недельный интервал, потому что за две недели можно натворить слишком много. Другие предпочитают интервал в две недели, так как боятся не успеть выполнить задание за неделю.
Рис. 1.4. Схема проекта
Нулевая итерация
Во время самой первой итерации, которую иногда называют нулевой, создается краткий список функций — историй. Об этом будет рассказано подробнее далее. А сейчас давайте их рассмотрим как функции, которые нужно разрабатывать.
В процессе нулевой итерации также происходит развертывание среды разработки, оценка историй и построение первоначального плана. Такой план — это просто предварительное распределение историй по нескольким первым итерациям. Наконец, во время нулевой итерации разработчики, в том числе и разработчики архитектуры, творят чудо — создают первоначальный проект на основе предварительного списка историй.
Процесс написания историй, их оценки, планирования и проектирования никогда не прекращается. Поэтому через всю схему ведения проекта проходит горизонтальная линия, обозначенная словом «исследование». В каждой итерации проекта, от его начала до конца, происходит анализ, проектирование и реализация. Согласно методологии Agile, постоянно нужно что-то анализировать и проектировать.
Некоторые думают, что Agile — это просто каскадная модель в миниатюре, которая повторяется многократно.
Это не так. Итерации не разделяются на три отрезка. В начале итерации выполняется не только сплошной анализ, а в конце — не только одна реализация. Скорее, анализ требований, архитектуры, проектирования и реализации непрерывно сопровождает всю итерацию.
Если вас это смущает, не переживайте. Об этом еще многое предстоит узнать в дальнейших главах. Просто имейте в виду, что итерации — не самая малая составляющая проекта при использовании Agile. Существует и много других уровней. Анализ, проектирование и реализация происходят на каждом из этих уровней. И все это не прерывается до самого конца.
Данные благодаря Agile
В начале первой итерации происходит оценка количества историй, которые нужно выполнить. Команда на протяжении всей итерации работает над выполнением собственно этих историй. О том, что происходит во время этой итерации, будет рассказано позже. Теперь скажите, что лишнего в работе команды, когда она пытается выполнить все истории, запланированные ранее?
Почти ничего. Так происходит из-за того, что разработка программного обеспечения плохо поддается точной оценке. Мы, программисты, просто не знаем, что сколько времени займет. Так происходит не потому, что мы тормозим или ленивы, а потому, что просто-напросто невозможно узнать, насколько сложно будет выполнить задание, до тех пор пока мы не принялись за него и не завершили. Но, как мы видим, не все так плохо.
В конце этой итерации будут выполнены некоторые фрагменты ранее запланированных задач. За счет этого мы можем предварительно измерить количество работы, выполняемой за одну итерацию. А это уже данные о том, как работа продвигается на самом деле. Если допустить, что все итерации будут схожи между собой, можно применить полученные данные для корректировки первоначального плана и рассчитать дату окончания проекта (рис. 1.5).
Рис. 1.5. Расчет новой даты завершения проекта
Этот расчет, вероятно, может огорчить. Почти всегда сроки будут в значительной мере выходить за рамки тех, которые были намечены изначально. С другой стороны, новые сроки основаны на действительных данных, поэтому не получится оставить их без внимания. Получившиеся сроки также не стоит принимать слишком близко к сердцу, так как они основаны лишь на одном замере. Погрешности при предварительном расчете данных довольно велики.
Чтобы уменьшить такие погрешности, должно пройти две, три и более итераций. По мере выполнения работ мы получаем больше данных о том, сколько историй выполняется за одну итерацию. Мы обнаружим, что их количество различается от итерации к итерации, но в среднем получается довольно стабильный расчет скорости продвижения. После четырех или пяти итераций у нас будет более ясное представление о сроках завершения проекта (рис. 1.6).
По мере прохождения итераций погрешности сводятся на нет, до тех пор пока не станет ясно, что первоначальный срок выполнения проекта в корне неверен.
Рис. 1.6. Чем больше итераций, тем проще рассчитать сроки сдачи проекта
Надежда против управления
Защита от самообмана — главная цель Agile. Мы применяем Agile, чтобы избавиться от ложных надежд, которые в итоге приведут проект к краху.
Надежды убивают проект. Надежды не позволяют команде сообщать менеджерам адекватные сведения о продвижении проекта. Когда менеджер спрашивает, как продвигаются дела, именно надежда толкает программистов на ответ «все хорошо!». Надежда — никудышный способ управления проектом по разработке программного обеспечения. А Agile — это ушат с холодной водой, который непрерывно и своевременно возвращает к действительности.
Некоторые думают, что Agile способствует скорости выполнения проекта. Это не так. Agile никогда не ставил своей целью выполнить и сдать проект поскорее. Agile помогает вовремя понять то, где и насколько мы облажались. Это нужно для того, чтобы успешно справиться с поставленными задачами. Теперь посмотрим, в чем заключается задача руководителя. Для ведения проекта руководители собирают данные и потом уже на их основе принимают наилучшие решения. Благодаря Agile можно получить необходимые данные. Много данных.
Руководители используют эти данные для того, чтобы привести проект к наилучшему исходу. Наилучший исход из возможных — не всегда то же самое, что и желаемый. Наиболее благополучный исход может очень разочаровать, особенно заинтересованные стороны, изначально вложившиеся в проект. Но наилучший исход из возможных по определению является лучшим, что можно получить от проекта.
Как справиться с правилом креста?
Теперь вернемся к правилу креста в управлении проектами: хорошо, быстро, дешево, готово. Учитывая данные, полученные при выполнении проекта, руководство команды программистов может определить, насколько хорошо, быстро, дешево и когда будет готов проект.
Руководители, отталкиваясь от таких сведений, могут вносить изменения в объем и график работ, коллектив и задавать планку для качества результата.
Изменения графика
Начнем с графика работ. Можно задать вопрос: а что, если проект будет завершен не первого ноября, а первого марта? Обычно такие разговоры напрягают. Помните, что сроки устанавливают по объективным деловым причинам. Причины, конечно же, остались теми же. Перенос сроков зачастую означает, что компания потерпит какие-то убытки.
С другой стороны, менеджеры временами устанавливают сроки произвольно, исходя из удобства. Например, в ноябре будет проходить выставка, и компания просто хочет показать себя и представить свой проект. Вероятно, в марте будет проходить настолько же подходящая для него выставка. Помните, что все равно еще рано говорить о сроках окончания. Прошло только несколько итераций проекта. Лучше сказать заинтересованным сторонам, что проект будет готов в марте, чем дождаться, когда они оплатят стенд на выставке, проходящей в ноябре.
Много лет назад я вел группу разработчиков, которые работали над проектом для телефонной компании. В разгар проекта стало ясно, что сдачу проекта придется отложить на полгода. Мы сообщили об этом руководству компании как можно раньше, насколько это вообще было возможно.
Руководство компании впервые столкнулось с тем, что их предупредили о переносе сроков вовремя. Они просто зааплодировали нам стоя.
Невероятно. Но было именно так. Один раз.
Расширение команды
Как правило, никакие компании не хотят переноса сроков. Сроки установлены по объективным деловым причинам, и эти причины все еще имеют место. Можно увеличить количество сотрудников. На первый взгляд кажется, что если команду расширить вдвое, то и дело пойдет вдвое быстрее.
Но на самом деле прямой взаимосвязи нет. Закон Брукса[25] гласит: «Если проект не укладывается в сроки, то добавление рабочей силы задержит его еще больше».
То, что происходит в реальности, можно увидеть на схеме, изображенной на рис. 1.7. Команда уже какое-то время работает над проектом с определенной отдачей. Приходят новички. Производительность проседает в течение нескольких недель, потому что новичкам необходимо учиться, и они донимают расспросами тех, кто уже работает давно. Хочется верить, что потом новички достаточно осваиваются и вносят свой вклад в проект.
Руководители делают ставку на то, что площадь под этой кривой будет строго положительна. Конечно, понадобится достаточно времени и усилий, для того чтобы компенсировать первоначальные потери.
Другой фактор: безусловно, расширение коллектива стоит денег. Зачастую это непозволительная роскошь для бюджета проекта. Итак, давайте предположим, что команду нельзя расширять. Тогда следует ожидать изменения качества.
Рис. 1.7. Истинное следствие расширения команды
Снижение качества
Очевидно, что если делать фуфло, то и работа пойдет быстрее. Тогда зачем что-то тестировать, зачем пересматривать код, зачем нужен какой-то непонятный рефакторинг? Просто пиши код, и пошло все к чертовой матери! Если надо, пиши код хоть восемьдесят часов в неделю, главное — жги!
Думаю, вы понимаете, что я хочу сказать. Что это бесполезно. Клепая фуфло, вы не достигнете быстроты, вы будете тормозить. Поверьте моему опыту, это кристально ясно, когда программируешь уже двадцать или тридцать лет. Нельзя делать ерунду быстро. Ерунда — это всегда тормоз.
Есть только один способ быстро продвигаться вперед — нормально работать.
Поэтому планку качества нужно поднять до максимума и не снижать. Если нужно ускорить продвижение, тут без вариантов — извольте повышать качество.
Изменения объема работ
Это последнее из того, что можно поменять. Возможно, но это не точно, некоторые запланированные функции совсем не обязательно нужно предоставить именно первого ноября.
Расспросим всех заинтересованных лиц: «Господа, если вы хотите получить весь нужный вам функционал, он будет только в марте. Если вам нужно получить полностью весь функционал к ноябрю, некоторые функции придется исключить». На что нам наверняка ответят: «Нет, мы ничего исключать не будем! Нам нужно все! И нужно к первому ноября». Однако мы справедливо на то возразим: «Да, но вы не понимаете. Если вам нужно все, что вы хотите, придется подождать марта». Заинтересованные стороны, вероятнее всего, продолжат бодаться: «Нет, мы хотим получить все необходимое! И к первому ноября!»
Такой спор будет продолжаться какое-то время, потому что никто не хочет давать задний ход. У партнеров есть моральное право требовать в этом разговоре то, что им нужно, зато у программистов есть данные. И при грамотном раскладе побеждает тот, кто владеет данными.
Если проект организован правильно, то заказчики в конечном итоге задумчиво покивают головой, соглашаясь со сказанным, и начнут тщательный пересмотр плана. По очереди, методом исключения, они определят тот функционал, который им нужен к ноябрю, как собаке пятая нога. Неприятно, но что поделать, если мы хотим адекватно организовать работу? Итак, план подгоняют под действительность. Некоторые функции оставляют на потом.
Порядок реализации функционала
Непременно будет так, что заказчики прицепятся к какой-то функции, которую мы уже реализовали, и скажут нам: «Позорище! Зачем вы это сделали? Нам это не надо».
Мы не хотим снова это выслушивать! Так что теперь в начале каждой итерации придется спрашивать заинтересованные стороны, какие функции реализовать следующими. Да, разные функции зависят друг от друга, но мы же программисты и должны справляться с этим. Так или иначе, мы будем реализовывать функции в том порядке, в котором попросят заинтересованные стороны.
Завершение обзора
Вот мы и рассмотрели Agile. Но пока что только издалека. В обзоре опущены многие подробности, но в нем вся суть гибкой методологии. Agile — это процесс, в котором проект разделяют на отрезки, называемые итерациями. Объем работ, проделанный во время каждой итерации, измеряют и исходя из этого выверяют график. Функционал реализуется в том порядке, в котором это удобнее заинтересованным сторонам. Функции, необходимые в первую очередь, реализуют в первую очередь.
Планку качества нужно держать как можно выше. График в основном зависит от объема выполняемых работ.
Это и есть Agile.
Жизненный цикл
Схема Рона Джеффриса, изображенная на рис. 1.8, объясняет принципы экстремального программирования. Эта схема также известна как «жизненный цикл».
Рис. 1.8. Жизненный цикл
Я посчитал, что для этой книги лучше всего подойдут методы экстремального программирования, потому что из всех методологий, составляющих Agile, экстремальное программирование является наиболее определенным, исчерпывающим и наименее замутненным.
Почти все прочие методологии, входящие в Agile, — это составляющие или разновидности экстремального программирования. Это не означает, что остальными методологиями, образующими Agile, нужно пренебрегать. Они могут быть очень ценны для различных проектов. Но чтобы понять, что такое Agile и с чем его едят, нет способа лучше, чем изучить экстремальное программирование. Оно прообраз, лежащий в основе Agile, который одновременно является его лучшей составляющей.
Кент Бек — отец экстремального программирования, а Уорд Каннингем — его дедушка. Эти два человека, работая совместно в компании Tektronix в середине 1980-х, исследовали множество идей, которые в конечном итоге породили экстремальное программирование. Впоследствии Бек придал этим идеям точную форму. Таким образом, около 1996 года появилось экстремальное программирование. В 2000 году Кент Бек обнародовал свою окончательную работу: Extreme Programming Explained: Embrace Change[26].
Жизненный цикл подразделяется на три кольца. Внешнее кольцо отражает методы экстремального программирования при взаимодействии с клиентами. Это кольцо, по сути, эквивалентно тому, что предлагает методология Scrum[27]. Эти методы обеспечивают структуру взаимодействия между командой разработчиков и клиентами, а также принципы, по которым заказчики и разработчики ведут управление проектом.
• Прием «игра в планирование» занимает центральное положение. Благодаря ему мы можем понять, как разбить проект по функциям, историям и задачам. Он содержит указания по оценке, постановке приоритетов, а также планированию соответствующих функций, историй и задач.
• Небольшие и частые релизы не позволяют команде «откусить» больше, чем возможно.
• Приемочное тестирование позволяет определять, какие функции реализованы, а также какие истории и задачи выполнены. Оно показывает команде, как определить однозначные показатели завершения.
• «Одна команда» позволяет понять, что в процессе разработки программного обеспечения принимают участие различные специалисты, в том числе программисты, тестировщики и руководители, а также то, что клиенты и сами принимают непосредственное участие, находясь на связи и будучи открытыми для вопросов. Все должны работать совместно для достижения общей цели.
Среднее кольцо жизненного цикла отражает методы экстремального программирования при взаимодействии внутри команды. Эти методы обеспечивают рамочную основу для взаимодействия между членами команды разработчиков, а также для самоуправления.
• Постоянный темп — это метод, который предохраняет команду разработчиков от перерасхода своих сил и банального выгорания до достижения финишной черты.
• Коллективное владение не позволяет членам команды тянуть одеяло на себя, благодаря чему каждый вносит посильный вклад в проект и несет ответственность за всю работу.
• Непрерывная интеграция позволяет команде сосредоточиться на частом слиянии рабочих копий в основную ветвь разработки и частом создании сборок, чтобы своевременно выявить ошибки и точнее отследить продвижение проекта.
• Метафора — это метод, который позволяет создавать и утверждать общую терминологию, благодаря которой команда разработчиков и клиенты находят понимание при обсуждении вопросов, связанных с проектом.
Внутреннее кольцо жизненного цикла представляет собой технические методы, которые позволяют направлять и в чем-либо ограничивать программистов для достижения наиболее высокого уровня качества.
• Парное программирование — это метод, который помогает членам команды делиться сведениями и сотрудничать в парах, в том числе проводить совместный анализ, чем достигается высокий уровень обеспечения точности и внедрения новшеств.
• Простота проектирования — это метод, который позволяет команде не расходовать силы впустую.
• Рефакторинг кода способствует непрерывному совершенствованию и доработке всего, что получается в ходе работы.
• Разработка через тестирование — это страховочный канат, благодаря которому команда технических специалистов может быстро выполнять работу, не снижая планку качества.
Все методы очень тесно связаны с целями, которые провозглашает Манифест Agile, по меньшей мере в том, что перечислено ниже:
• Люди и взаимодействие важнее процессов и инструментов.
• «Одна команда», метафора, коллективное владение, парное программирование, 40-часовая рабочая неделя.
• Работающий продукт важнее исчерпывающей документации.
• Приемочное тестирование, разработка через тестирование, простота проектирования, рефакторинг кода, непрерывная интеграция.
• Сотрудничество с заказчиком важнее согласования условий контракта.
• Небольшие и частые релизы, игра в планирование, приемочное тестирование, метафора.
• Готовность к изменениям важнее следования первоначальному плану.
• Небольшие и частые релизы, игра в планирование, 40-часовая рабочая неделя, разработка через тестирование, рефакторинг кода, приемочное тестирование.
Однако по мере знакомства с этой книгой можно будет заметить, что связи между жизненным циклом и Манифестом Agile гораздо глубже и теснее, чем упрощенная модель, которая приведена выше.
Заключение
Таков Agile и история его появления. Agile — небольшая дисциплина, помогающая решению небольших задач, поставленных небольшими командами программистов для управления небольшими продуктами. Но несмотря на то что Agile невелик сам по себе, его значение и влияние достаточно велико, поскольку все большие проекты так или иначе состоят из множества маленьких.
С каждым днем программное обеспечение все больше переплетается с нашей повседневностью. Число людей, не мыслящих свою жизнь без него, постоянно растет. Не побоюсь сказать, что без программного обеспечения Земля перестанет вертеться. Если Земля остановится без программного обеспечения, то Agile — именно то, что позволяет наилучшим образом вести его разработку.
Глава 2. Почему же Agile?
Прежде чем углубиться в тонкости разработки с помощью Agile, хотелось объяснить, что стоит на кону. Agile важен не только для отрасли разработки программного обеспечения, но и для промышленности, общества и, наконец, всей цивилизации.
Разработчики и руководители зачастую прибегают к Agile в силу каких-то временных обстоятельств. Они могут использовать его потому, что считают правильным подходом, или, возможно, просто потому, что купились на обещания уложиться в минимальные сроки при достижении самого высокого качества. Причины неосязаемы, неясны и могут противоречить друг другу. Многие отказались от Agile просто потому, что не смогли незамедлительно обрести ожидаемого, поскольку восприняли обещанное буквально.
Agile важен не по причинам, вызванным изменчивыми обстоятельствами. Agile важен в силу куда более глубоких философских и этических причин. Эти причины связаны с профессиональной деятельностью и обоснованными ожиданиями наших клиентов.
Профессионализм
Agile привлекает меня тем, что ставит на первое место дисциплину, а не церемониальность. Чтобы правильно применять Agile, нужно работать в парах, в первую очередь писать тесты, проводить рефакторинг кода и соблюдать правила простоты проектирования. Придется работать короткими циклами, получая в результате каждого из них рабочий результат. А еще придется постоянно и непрерывно взаимодействовать с клиентами.
Взгляните на жизненный цикл и рассмотрите каждый из приведенных методов как обещание или обязательство — вам станет понятно, откуда ноги растут. Для меня Agile — это очередной виток мастерства и приверженность идее продвигать профессиональный подход к работе по всей индустрии разработки ПО.
В этой отрасли крайне важно повышать профессионализм. Мы слишком часто терпим крах. Слишком много занимаемся ерундой. Миримся с чрезмерным количеством ошибок. Заключаем ужасные сделки. Слишком часто мы ведем себя как сопляки, которым дали кредитку. Раньше все было проще, можно было позволить себе тормозить, так как на кону стояло меньше, чем сейчас. В 1970-х и 80-х, и даже в 1990-х цена ошибки в программе была не так высока. По крайней мере, убытки были ограниченны и контролируемы.
Куда ни глянь, везде оно!
Времена меняются.
Прямо сейчас оглянитесь вокруг. Даже не надо вставать со своего места, просто оглянитесь на то, что в комнате вокруг вас. Сколько компьютеров в комнате?
Давайте теперь я. Сейчас я в своем летнем домике, который находится в лесу на севере штата Висконсин. Давайте посчитаем, сколько компьютеров и процессоров в них у меня здесь?
• 4. Я набираю этот текст на ноутбуке Mac Book Pro с четырьмя ядрами. Производитель заявляет, что их восемь, но не стану считать виртуальные ядра. Также не стану брать в счет все малые вспомогательные процессоры, которые используются в MacBook.
• +1. Мышь Apple Magic Mouse 2. Уверен, что там больше одного процессора, но буду все считать за один.
• +1. Планшет iPad с монитором Duet в качестве дополнительного. Мне прекрасно известно, что в iPad много малых процессоров, но все равно посчитаю как один.
• +1. Ключ от машины (!).
• +3. Наушники Apple AirPods. По одному для каждого наушника и еще один в зарядном кейсе. Вероятно, процессоров больше, ну и ладно…
• +1. Мой iPhone. Да-да, на самом деле в iPhone, вероятно, около дюжины процессоров, но все равно, пускай будет один.
• +1. Взгляд упал на ультразвуковой датчик движения (в доме их куда больше, но я вижу и посчитаю один).
• +1. Термостат.
• +1. Панель управления системой безопасности.
• +1. Телевизор с плоским экраном.
• +1. DVD-проигрыватель.
• +1. Устройство для воспроизведения IP-телевидения Roku.
• +1. Apple AirPort Express.
• +1. Apple TV.
• +5. Пульты дистанционного управления.
• +1. Телефон (да, именно телефон).
• +1. Имитация камина (вы бы видели, какую красотищу он может выдавать!).
• +2. Старенький телескоп Meade LX 200 EMC с компьютером. Один процессор в приводе, а другой — в переносном блоке управления.
• +1. Флэшка у меня в кармане.
• +1. Стилус Apple pencil.
На свою душу я насчитал, по крайней мере, 30 компьютеров, и это только в этой комнате. Действительное количество можно увеличить примерно вдвое, поскольку в большинстве устройств по несколько процессоров. Но пока что давайте остановимся на тридцати.
А сколько насчитали вы? Уверен, что у большинства из вас получилось примерно столько же, сколько у меня. Действительно, бьюсь об заклад, что почти у каждого из 1,3 млрд человек, проживающих в западном мире, постоянно имеется рядом не один десяток компьютеров. Это что-то новое. В начале 1990-х это число в среднем было бы близко к нулю.
Что общего у всех компьютеров, которые мы видим рядом с собой? Их все надо программировать. Для них нужно программное обеспечение, которое как раз мы и пишем. И как вы думаете, каково качество этих программ?
Хорошо. Давайте рассмотрим вопрос с другого бока. Сколько раз на дню ваша бабушка пользуется программным обеспечением? У тех из вас, у кого она еще жива, дай бог ей здоровья, счет может идти на тысячи, потому что в современном обществе почти ничего нельзя сделать, не прикасаясь к программному обеспечению. У вас не получится:
• Говорить по телефону.
• Купить или продать что-либо.
• Пользоваться микроволновкой, холодильником или даже тостером.
• Постирать или высушить одежду.
• Помыть посуду.
• Слушать музыку.
• Водить машину.
• Подать страховую претензию.
• Регулировать температуру в помещении.
• Смотреть телевизор.
Но дела обстоят еще хуже. Сейчас в цивилизованном обществе буквально ничего значительного нельзя сделать без работы с программным обеспечением. Не получится рассмотреть, принять или привести в действие никакой закон. Правительство не сможет вынести на обсуждение ни один политический вопрос.
Самолеты не смогут летать. Машины не смогут ездить. Не получится запустить ракеты. Корабли не смогут ходить. На дороги станет невозможно нанести покрытие, не получится собрать урожай, остановится производство на сталелитейных заводах, автозаводы не смогут производить автомобили, кондитерские фабрики не произведут сладостей, прекратятся торги на биржах…
Без программного обеспечения наше общество сейчас как ноль без палочки. Каждое мгновение, когда мы не спим, мы сталкиваемся с программами. А многие даже во сне с ними сталкиваются — отслеживают фазы сна.
Куда без нас, программистов?
Наше общество сейчас целиком и полностью зависит от программного обеспечения. Оно стало играть роль крови, текущей в жилах нашего общества. Без него блага цивилизации, которыми мы сейчас наслаждаемся, были бы невозможны.
И кто пишет все программное обеспечение? Такие, как мы. Куда обществу без нас, программистов?
Другие думают, что их вклад в цивилизацию наиболее важен. Но они передают плоды своих трудов нам, а мы, в свою очередь, пишем алгоритмы, по которым работает различная техника, позволяющая отслеживать и задавать тон буквально всей деятельности в современном мире.
Получается, что без нас, программистов, никто не может и пальцем пошевелить.
Но в целом мы работаем плохо.
Как думаете, какая доля ПО, которое присутствует почти везде, протестирована должным образом? Сколько программистов могут сказать, что у них есть тестовый набор, который подтверждает с высокой долей вероятности, что программы, которые они написали, работают?
Работают ли сотни миллионов строк кода, из которого состоит ПО вашего автомобиля? Вы находили какие-нибудь ошибки в них? Я находил. А что скажете насчет кода, под управлением которого работают тормоза, газ и рулевой механизм? Там есть ошибки? Существует ли тестовый набор, который можно запустить в любое время и который подтвердит с высокой вероятностью, что когда ваша нога нажмет на педаль тормоза, машина действительно остановится?
Сколько людей погибло из-за того, что программное обеспечение в их автомобилях не смогло правильно отреагировать на давление ноги водителя на педаль тормоза? Точно сказать нельзя, но много. В 2013 году «Тойота» потерпела миллионные убытки, поскольку ПО содержало «возможное инвертирование разрядов, смертельные задачи, влекущие нарушение отказоустойчивости, повреждение содержимого оперативной памяти, одиночные неисправности элементов, влекущие за собой отказ всей системы, несовершенство защиты от переполнения стека и буфера, одиночные неисправности отказоустойчивых систем и тысячи глобальных переменных», а сам код был запутан, как «спагетти»[28].
Программы, написанные нами, приводят к гибели людей. Что я, что другие наверняка становятся программистами не для того, чтобы кого-то убивать. Многие из нас постигли искусство программирования, потому что, еще будучи детьми, мы писали бесконечные циклы, которые выводили наши имена на экран, и нам это казалось невероятно крутым. Но сейчас от наших действий зависят жизни и судьбы. И с каждым днем появляется все больше кода, который ставит на кон жизни и судьбы все большего количества людей.
Катастрофа
Однажды наступит день, если еще не наступил, когда какой-нибудь несчастный программист по небрежности натворит глупостей, которые приведут к гибели десятка тысяч людей за раз. Задумайтесь об этом на минутку. Несложно представить себе несколько вероятных сценариев. И если так случится, то политики всего мира поднимутся в праведном гневе (как и полагается) и недвусмысленно укажут пальцем на нас.
Должно быть, вы подумаете, что пальцем покажут на наше начальство или руководство наших компаний, но мы отлично помним, что было, когда пальцем показали на исполнительного директора североамериканского подразделения «Фольксваген», и он предстал перед Конгрессом. Политики поинтересовались, зачем «Фольскваген» устанавливал в свои автомобили программное обеспечение, которое целенаправленно обманывало оборудование для испытаний на количество и качество выбросов, которое применяется в Калифорнии. Он ответил: «Это не решение компании, насколько я знаю, менеджеры не имеют к этому отношения. Это сделала пара программистов, исходя из каких-то своих целей»[29].
Получается, в итоге крайними выставят нас. И это правильно. Потому что именно наши пальцы стучали по клавиатуре, набирая код, наша дисциплина хромала на обе ноги, а самой первопричиной послужила наша беспечность.
Именно это отдавалось эхом в моей голове, когда я возлагал большие надежды на Agile. Тогда, как и сейчас, я надеялся, что дисциплина, обретенная благодаря Agile, станет первым шагом навстречу тому, чтобы сделать профессию программиста по-настоящему почетной.
Разумные ожидания
Далее приведен вполне разумный список того, чего ожидают от нас руководство, пользователи и клиенты. Обратите внимание, что по мере прочтения списка, с одной стороны, вы согласны, что все эти ожидания вполне обоснованны. А с другой стороны, если в вас заговорит программист, будет страшновато. С точки зрения программиста сложно представить, как можно оправдать такие ожидания.
Соответствие этим ожиданиям — это одна из основных целей Agile.
Принципы и методы Agile напрямую затрагивают большую часть ожиданий из этого списка. Подобное отношение к работе требует от своего коллектива любой хороший технический директор. Чтобы понять эту точку зрения, представьте, что я и есть ваш технический директор. И вот что я от вас ожидаю.
Фирма веников не вяжет!
Неприятно, что в нашей сфере вообще приходится упоминать о том, что код нужно писать качественно. А что поделать? Я уверен, дорогие читатели, что многим из вас довелось хотя бы раз не оправдать это ожидание. Мне доводилось.
Чтобы понять всю глубину проблемы, рассмотрим отключение сети управления движением воздушного транспорта над Лос-Анджелесом из-за сброса даты 32-битных часов. Или отключение всех двигателей на борту самолета Boeing 787 по той же причине. Или сотни жертв крушения Boeing737 Max из-за сбоя системы MCAS.
А как насчет моего собственного опыта с сайтом healthcare.gov на заре его существования? После первого входа, как и на многих современных сайтах, в целях защиты от взлома мне нужно было ответить на ряд вопросов. Одним из вопросов был «запоминающаяся дата». Я ввел: 21.07.73. Сайт мне выдал, что я ввел неправильное значение.
Я программист. И знаю образ мышления программистов. В итоге я попробовал ввести дату в разных форматах: 21/07/73, 21–07-1973, 21July1973, 21071973 и тому подобное. Результат был одинаков. Неправильное значение. Я расстроился. Что за приколы? Какой формат вам еще нужен?
Потом меня осенило. Программист, написавший код для сайта, не знал, какие вопросы будут задаваться. Он просто выдергивал вопросы из базы данных и сохранял ответы. Этот программист, вероятно, не предусмотрел поддержку нестандартных символов и чисел для ответов. Так что я набрал «годовщина свадьбы». Наконец, получилось.
Думаю, что вполне справедливо сказать, что любая система, которая требует от пользователя мышления программиста, чтобы ввести какие-либо данные, — дрянь.
В этом разделе я мог бы рассказать массу историй об отстойном программном обеспечении. Но другие уже сделали это намного лучше. Если вам хочется ближе ознакомиться с масштабами этой проблемы, советую почитать книгу Гойко Аджича Humans vs Computers[30] и книгу Мэтта Паркера Humble Pi[31].
Вполне разумно, что боссы, клиенты и пользователи ждут от нас программ высокого качества с наименьшими недочетами. Никому не нужна ерунда, особенно если заплачены приличные деньги.
Обратите внимание, что упор Agile на тестирование, рефакторинг, простоту проектирования и обратную связь с заказчиком — это очевидное лекарство от низкого качества кода.