Современная программная инженерия. ПО в эпоху эджайла и непрерывного развертывания - Дэвид Фарли - E-Book

Современная программная инженерия. ПО в эпоху эджайла и непрерывного развертывания E-Book

Дэвид Фарли

0,0

Beschreibung

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

Sie lesen das E-Book in den Legimi-Apps auf:

Android
iOS
von Legimi
zertifizierten E-Readern
Kindle™-E-Readern
(für ausgewählte Pakete)

Seitenzahl: 339

Veröffentlichungsjahr: 2023

Das E-Book (TTS) können Sie hören im Abo „Legimi Premium” in Legimi-Apps auf:

Android
iOS
Bewertungen
0,0
0
0
0
0
0
Mehr Informationen
Mehr Informationen
Legimi prüft nicht, ob Rezensionen von Nutzern stammen, die den betreffenden Titel tatsächlich gekauft oder gelesen/gehört haben. Wir entfernen aber gefälschte Rezensionen.



Дэвид Фарли
Современная программная инженерия. ПО в эпоху эджайла и непрерывного развертывания
2023

Переводчик М. Трусковская

Дэвид Фарли

Современная программная инженерия. ПО в эпоху эджайла и непрерывного развертывания. — СПб.: Питер, 2023.

ISBN 978-5-4461-2335-3

© ООО Издательство "Питер", 2023

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

О книге «Современная программная инженерия»

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

Гленн Вандербург (Glenn Vanderburg), технический директор Nubank

Отдельным техникам программной инженерии посвящено множество книг. Эта книга — иная. Дэйв рассматривает самую суть программной инженерии и то, чем она отличается от простой разработки. Он объясняет, почему высоко-классный инженер ПО должен быть экспертом в управлении сложностью, как освоить уже существующие техники и научиться оценивать потенциал всевозможных инженерных идей. Эта книга для тех, кто считает разработку ПО действительно инженерной дисциплиной, — неважно, новичок ли он в этой сфере или занимается разработкой уже не одно десятилетие.

Дэйв Хаунслоу (Dave Hounslow), инженер-разработчик

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

Майкл Найгард (Michael Nygard), автор книги Release IT, программист, архитектор ПО

Я прочитал книгу Дэйва Фарли и могу сказать: это действительно то, что нужно. Ее должен прочесть каждый, кто хочет стать инженером-разработчиком ПО или отточить свое мастерство в этой сфере. Она содержит полезные практические советы. Ее стоит включить в программу вузов и учебных центров.

Брайан Финстер (Bryan Finster), ыстарший инженер и ведущий архитектор USAF Platform One

Эту книгу я посвящаю своей жене Кейт и сыновьям Тому и Бену.

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

Том и Бен — парни, которыми я восхищаюсь и которых люблю. Работая над этой книгой, я был счастлив также вести с ними несколько совместных проектов. Спасибо за вашу помощь и поддержку.

Вступительное слово

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

К моменту поступления в вуз я не была новичком в программировании и даже разработала систему учета для университетской библиотеки. Но я ощутила себя сбитой с толку. Мне казалось, что программная инженерия — это что-то исключительно про разработку и написание кода.

После выпуска, в начале 2000-х, я работала в ИТ-отделе крупного автомобильного концерна. Как и следовало ожидать, мы занимались программной инженерией. Именно там я впервые (и далеко не в последний раз) столкнулась с диаграммой Ганта и водопадной моделью разработки. Я увидела, что команды все основное время уделяют сбору требований и проектированию и в гораздо меньшей степени — написанию кода, что, само собой, оборачивалось затратами на тестирование, на которое оставалось не слишком много времени.

Казалось, что программная инженерия — это создание приложений, полезных нашим клиентам.

Как многих других разработчиков, меня это не совсем устраивало.

Я изучила экстремальное программирование и Scrum. Я хотела работать в команде, применяющей agile-подход, поэтому в поисках этого подхода сменила несколько компаний. Многие из них утверждали, что они «эджайл», но по факту все ограничивалось тем, что мы записывали требования или задачи на карточках и развешивали их на стене, называя неделю спринтом. Разработчики должны были в конце каждого спринта закрывать определенное количество карточек, чтобы уложиться в произвольно заданные сроки. Очевидно, что отход от традиционного представления о программной инженерии тоже не работал.

Имея за плечами десятилетний опыт разработчика, я пришла на собеседование на Лондонскую финансовую биржу. Руководитель отдела разработки рассказал мне, что они используют методы экстремального программирования, разработку через тестирование (test-driven development, TDD), а также парное программирование. По его словам, они занимались чем-то вроде непрерывной доставки (сontinuous delivery), которая представляла собой непрерывную интеграцию продукта параллельно с его разработкой.

Я работала до этого в крупных инвестиционных банках, где развертывание занимало минимум 3 часа, а необходимые инструкции и списки выполняемых вручную команд для «автоматизации» занимали 12 страниц. Непрерывная доставка — это звучало здорово только в теории.

Руководителем отдела разработки был Дэйв Фарли, и когда я пришла в компанию, он трудился над книгой «Continious Delivery»1.

Мы проработали вместе 4 года, которые действительно изменили мою жизнь и карьеру. Мы на самом деле занимались парным программированием, TDD и непрерывной доставкой. Я узнала, что такое разработка через поведение, автоматизированное приемочное тестирование, предметно-ориентированное проектирование, разделение ответственности, уровни защиты от коррупции, что значит почувствовать машину и какие бывают уровни абстракции.

Я научилась создавать высокопроизводительные приложения с низкой задержкой на Java. Я наконец-то поняла, что означает нотация «О-большое» и как она применяется на практике. В общем, я реально использовала все те знания, которые получила в университете и которые почерпнула из книг.

Причем эти знания на самом деле помогли создать качественный высокопроизводительный продукт, который делал что-то новое. Ко всему прочему, мы были счастливы, и работа приносила удовлетворение. Мы не задерживались допоздна, у нас не было авралов перед релизами. А код не усложнялся со временем и его было легко поддерживать. Мы регулярно и последовательно внедряли новые функции и увеличивали ценность для бизнеса.

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

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

Как developer-адвокат, я общаюсь с сотнями разработчиков из разных компаний и сфер бизнеса, и они рассказывают мне о своих болевых точках (многие из которых даже сейчас не очень отличаются от тех, что я наблюдала 20 лет назад) и об историях успеха. Концепции, которые Дэйв сформулировал в книге «Современная программная инженерия», достаточно общие, чтобы их можно было применить во всех этих сферах, и достаточно конкретные, чтобы приносить практическую пользу.

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

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

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

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

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

Говоря о создании, я совершенно не имею в виду страницы кода или конкретные диаграммы, а скорее то, как всесторонне продумать код, прежде чем его написать. Когда я работала вместе с Дэйвом, я заметила, как мало времени он тратит на то, чтобы ввести сам код. Оказывается, если как следует продумать код, прежде чем писать его, мы сэкономим огромное количество времени и сил.

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

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

«Современная программная инженерия» помогла мне понять, почему мы чувствовали себя успешными и удовлетворенными все то время, пока работали с Дэйвом. Я надеюсь, что опыт и советы, которые вы получите, прочитав эту книгу, помогут вам так же, как если бы Дэйв Фарли трудился в вашей команде.

Удачи в разработке!

Триша Джи (Trisha Gee), developer-адвокат и Java Champion

1 На русском языке книга была издана под названием «Непрерывное развертывание ПО. Автоматизация процессов сборки, тестирования и внедрения новых версий программ». Общепринятым при этом является термин «непрерывная доставка». — Примеч. пер.

Введение

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

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

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

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

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

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

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

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

Мы узнаем, что в действительности означает программная инженерия. И это не всегда то, что мы ожидаем.

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

Все прежние определения программной инженерии были чересчур прескриптивными, они базировались на перечне конкретных инструментов и технологий. Инженерия — это больше, чем код, который мы пишем, и инструменты, которые мы используем. Это не технологическое проектирование, и технология — это не наша задача. Если, когда я произношу слово «инженерия», вы начинаете думать о чем-то бюрократическом, перечитайте эту книгу.

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

Чтобы наши ожидания оправдались, инженерия должна помогать лучше и эффективнее справляться со стоящими перед нами проблемами.

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

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

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

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

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

Определение программной инженерии

В этой книге мы будем придерживаться следующего определения:

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

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

• Теоретическая наука и инженерия как ее практическое применение — жизненно важные инструменты для достижения эффективного технического прогресса.

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

• Наконец, системы, которые мы создаем, обычно очень сложны, и их сложность со временем все возрастает. Поэтому чтобы успешно их разрабатывать, нам необходимо стать экспертами в управлении сложностью.

Структура книги

В первой части «Что такое программная инженерия» я разбираю, что действительно представляет собой инженерия в контексте программного обеспечения. Здесь описаны принципы и философия инженерии, а также то, как применять эти идеи в разработке ПО. Это технические основы разработки программного обеспечения.

Во второй части «Оптимизация для обучения» я расскажу, как организовать свою работу, чтобы она была успешной. Как определить, действительно ли мы движемся вперед или всего-навсего создаем то, что завтра уже устареет?

Третья часть «Оптимизация для управления сложностью» содержит описание принципов и методик, необходимых для управления сложностью. Здесь я разберу эти принципы более подробно и по существу, а также покажу, как применять их для создания высококачественных продуктов в любой сфере.

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

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

Благодарности

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

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

Я благодарен моему родственнику Бернарду Маккарти (Bernard McCarty) за идеи в рамках научного подхода и за то, что помог мне задуматься, почему я стремлюсь уделять столько же внимания экспериментам и наблюдениям, сколько остальным вещам.

Я благодарен Трише Джи не только за отличное вступительное слово, но и за то, что она поддерживала во мне энтузиазм, когда я в этом нуждался.

Я благодарен Мартину Томпсону (Martin Thompson) за обмен мнениями в сфере computer science и за то, что он всегда мгновенно отзывался на мои зачастую спонтанные мысли.

Я благодарен Мартину Фаулеру (Martin Fowler), который, несмотря на чрезвычайную занятость своими проектами, дал мне несколько советов — они позволили заметно улучшить эту книгу.

Многие мои друзья: Дэйв Хаунслоу, Стив Смит (Steve Smith), Крис Смит (Chris Smith), Марк Прайс (Mark Price), Энди Стюарт (Andy Stewart), Марк Краузер (Mark Crowther), Майк Баркер (Mike Barker) и другие — на протяжении нескольких лет помогали мне формировать свой взгляд на эту тему и не только на нее.

Я благодарен команде издательства Pearson за их помощь и поддержку в публикации книги.

Я также благодарен множеству людей — и не всех из них я знаю лично, — кто поддерживал, спорил, заставлял задуматься. Несколько лет я черпал их идеи в Twitter и на своем канале YouTube, где мне удалось наладить несколько очень продуктивных диалогов. Спасибо вам!

Об авторе

Дэвид Фарли — пионер в области непрерывной доставки, лидер мнения и эксперт-практик в сфере непрерывной доставки, автоматизации технологических процессов, разработки через тестирование и общей разработки ПО.

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

Дэвид — соавтор книги «Continuous Delivery», получившей премию Jolt Award, постоянный участник конференций и автор успешного и популярного YouTube-канала Continuous Delivery, посвященного программной инженерии. Он — разработчик одной из самых быстрых в мире финансовых бирж, пионер разработки через поведение, автор Манифеста реактивных систем и лауреат премии Duke Award за создание открытого продукта с использованием LMAX Disruptor.

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

Twitter: @davefarley77

YouTube-канал: https://bit.ly/CDonYT

Блог: http://www.davefarley.net

Сайт компании: https://www.continuous-delivery.co.uk

От издательства

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

Ваши замечания, предложения, вопросы отправляйте по адресу [email protected](издательство «Питер», компьютерная редакция).

Мы будем рады узнать ваше мнение!

На веб-сайте издательства www.piter.com вы найдете подробную информацию о наших книгах.

I. Что такое программная инженерия

Глава 1. Введение

Инженерия — практическое применение теоретической науки

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

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

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

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

• Описание. Понаблюдайте за текущим состоянием и опишите его.

• Гипотеза. Создайте теорию, которая может объяснить ваше наблюдение.

• Предположение. Сформулируйте предположение на основе гипотезы.

• Эксперимент. Протестируйте свое предположение.

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

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

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

Что такое программная инженерия?

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

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

Это означает, что мы должны управлять сложностью создаваемых систем таким образом, чтобы поддерживать способность изучать новое и приспосабливаться к нему.

Поэтому нам необходимо стать экспертами в познании и в управлении сложностью.

Чтобы стать экспертами в познании, нам придется освоить пять техник:

• итерации;

• сбор и анализ обратной связи;

• инкрементализм;

• экспериментирование;

• эмпиризм.

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

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

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

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

Чтобы стать экспертами в управлении сложностью, нам понадобится применять следующие подходы:

• модульность;

• связность (cohesion);

• разделение ответственности (separation of concerns);

• абстракцию;

• слабую связанность, или сцепление (loose coupling).

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

В книге рассказано, как преобразовать эти подходы в инструменты разработки. А теперь я перечислю несколько практических инструментов для повышения эффективности любого процесса разработки:

• тестируемость (testability);

• развертываемость (deployability);

• скорость;

• управление переменными;

• непрерывная доставка.

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

И все это основано на данных.

Переосмысление понятия программной инженерии

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

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

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

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

Именно такой идеей я руководствовался при создании последовательной модели, которая способна объединить основные принципы и позволяет надеяться на успех разработки.

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

Как добиться успеха

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

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

Опасность этого подхода в том, что при неправильном применении он может породить стиль мышления и поведения, основанный на поклонении авторитетам.

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

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

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

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

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

Зарождение программной инженерии

Понятие программной инженерии сформировалось в конце 1960-х годов. Этот термин был впервые использован Маргарет Хэмилтон (Margaret Hamilton), которая позже стала руководителем подразделения программной инженерии в Инструментальной лаборатории Массачусетского технологического института. Маргарет возглавляла разработку программного обеспечения для контроля полетов в рамках космической программы «Аполлон».

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

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

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

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

Конференция под эгидой НАТО была посвящена в том числе и поиску решения этой проблемы.

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

Спустя несколько лет лауреат премии Тьюринга Фред Брукс (Fred Brooks) сравнил степень развития программных и технических средств:

Ни в одной технологии или управленческой технике не существует универсального метода, увеличивающего на порядок производительность, надежность и простоту3.

Брукс исходил из знаменитого закона Мура4 для долговременного развития аппаратных средств.

Это интересное наблюдение, которое, полагаю, удивит многих, но по сути своей оно абсолютно верно.

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

Следует считать необычным не то, что прогресс в программировании идет так медленно, а то, что он так быстр в аппаратном обеспечении компьютеров. Ни одна другая технология за всю историю цивилизации не имела за 30 лет своего развития роста соотношения “производительность/цена” на шесть порядков.

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

Меняя парадигму

Идея смены парадигмы была разработана физиком Томасом Куном (Thomas Kuhn).

Познание зачастую подобно приращению. Мы добавляем все новые уровни понимания и каждый последующий основываем на предыдущем.

Однако познание не всегда бывает таким. Иногда мы радикальным образом меняем свои взгляды на изучаемое явление. Это позволяет нам постигать новое. Но это также означает, что мы должны отринуть старое.

В XVIII столетии авторитетные биологи (тогда их так еще не называли) считали, что некоторые виды животных способны к самозарождению. В середине XIX века Ч. Дарвин описал процесс естественного отбора, и это окончательно поставило крест на теории самозарождения.

Такие изменения мышления привели к современному пониманию генетики и способности познавать жизнь на фундаментальном уровне, создавая технологии, которые позволяют управлять генами, разрабатывать вакцины от Covid-19 и генетические лекарства.

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

Смена парадигмы предполагает отказ от тех идей, которые, как нам стало известно, не соответствуют истине.

Абсолютно верно рассматривать разработку как истинно инженерную дисциплину, основанную на философии научного метода познания и научного рационализма.

Это верно не только благодаря ее влиянию и эффективности, так красноречиво описанным в книге «Ускоряйся!»5, но и благодаря насущной потребности отбрасывать идеи, которые не удовлетворяют подходу.

Это позволяет нам более эффективно обучаться и отбирать только стоящие идеи.

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

Итоги

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

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

2 На основании данных отчетов State of DevOps и отчетов Microsoft и Google.

3 Источник: Брукс Ф. Серебряной пули нет. 1986.

4 В 1965 году Гордон Мур предсказал, что плотность размещения (не производительность) транзисторов будет удваиваться каждый год. Затем он пересмотрел свой прогноз до двух лет на следующее десятилетие, до 1975 года. Этот прогноз был взят за основу производителями полупроводников и значительно превзошел ожидания Мура, сбывшись десятилетиями позже. Некоторые исследователи считают, что мы приближаемся к завершению взрывного роста мощностей, поскольку современные подходы исчерпали себя, а также из-за влияния эффекта квантования. Но на то время развитие полупроводников шло в соответствии с законом Мура.

5 Форсгрен Н., Хамбл Дж., Ким Дж. Ускоряйся! Наука DevOps: Как создавать и масштабировать высокопроизводительные цифровые организации.

Глава 2. Что такое инженерия?

Я разговариваю с людьми о программной инженерии уже несколько лет. В результате я регулярно оказываюсь втянут в дискуссии о строительстве мостов. Обычно они начинаются с фразы: «Да, но программы не строят мосты», — как будто это какое-то откровение.

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

Производственная инженерия — сложная сфера: вам нужно создавать материальные вещи с определенным уровнем точности и качества.

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

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

Производство не наша проблема

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

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

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

Если только мы не ошиблись с ее выбором, производством для нас должен стать запуск сборки (билда)!

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

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

Инженерия проектная, а не производственная

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

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

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

Это сложно, поскольку вы работаете с физическим объектом и не можете быстро его изменять.

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

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

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

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

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

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

Инженерия как математика

В конце 1980-х — начале 1990-х годов начались разговоры о более структурном подходе к программированию. Размышления о значении программной инженерии переросли в оценку способов, которыми мы создаем код. В частности, как организовать работу таким образом, чтобы более эффективно выявлять и устранять проблемы в наших моделях и реализациях?

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

Проблема в том, что сложно написать код для комплексной системы, но еще сложнее — тот, который определяет поведение подобной системы и одновременно подтверждает свою правильность.

Формальные методы — идея привлекательная, но они не получили широкого распространения на практике, поскольку с точки зрения производства они не упрощают, а наоборот, затрудняют процесс создания кода.

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

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

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

Программа — цифровой инструмент, который работает на детерминированных устройствах — компьютерах. Поэтому для некоторых узких контекстов, если проблема достаточно проста, ограниченна, определена и имеет небольшую изменчивость, формальные методы могут быть эффективны. Сложность здесь представляет определение степени детерминированности всей системы. Если система обладает параллелизмом, взаимодействует с реальным миром (людьми) или работает в чрезвычайно сложных областях, то ее теоретическая эффективность становится недоказуемой.

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

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

Такая кажущаяся простой вещь, как замена 4-миллиметровой нержавеющей стали 3-миллиметровой, может считаться в значительной степени контролируемым изменением. SpaceX оперирует подробными данными о пределе прочности металла на разрыв, собранными в результате экспериментов: они точно показывают степень прочности емкостей высокого давления, изготовленных из 4-миллиметровой стали.

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

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

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

В своем потрясающем выступлении Real Software Engineering (Настоящая программная инженерия)8 Гленн Вандербург говорит, что в других областях «инженерия — это то, что работает», а в разработке ПО почти все наоборот.

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

Тяжеловесный подход не добавлял существенной ценности процессу разработки. Вандербург говорит так:

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

С какой стороны ни посмотри, это не инженерия.

Определение инженерии как «того, что работает», данное Вандербургом, очень важно. Если практики, которые мы определяем как инженерные, не позволяют нам быстрее создавать лучшее ПО, то инженерными их считать нельзя!

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

Итак, если наше понимание инженерии зачастую ошибочно, то что же оно все-таки означает?

Первый инженер-программист

В то время когда Маргарет Гамильтон руководила разработкой системы управления полетом «Аполлона», правил игры еще не существовало. По ее словам, «мы разрабатывали свои инженерные правила на основе каждого открытия, которое мы делали, а высшее руководство НАСА от предоставления полной свободы перешло к чрезмерной бюрократии».

В то время у нас было очень мало опыта реализации таких сложных проектов, поэтому команда часто открывала совершенно новые горизонты. Задачи, стоявшие перед Гамильтон и ее командой, были очень сложными. В 1960-е годы никто не знал об исправлении ошибки переполнения стека.

Вот как Гамильтон описывает некоторые сложности:

Программное обеспечение космической миссии должно быть пригодным для использования человеком. Оно не только должно работать — но работать впервые. Помимо исключительной надежности, оно должно обнаруживать ошибки и выполнять восстановление в реальном времени. Языки, которые мы использовали, позволили нам смоделировать самые трудно обнаруживаемые ошибки. Мы сами придумывали правила разработки. Результаты, которые мы получили после обработки ошибок, зачастую оказывались неожиданными.

В то же время на разработку ПО в целом в сравнении с другими, более «взрослыми», формами инженерии смотрели свысока, как на какого-то бедного родственника. Гамильтон придумала термин «программная инженерия», чтобы коллеги из других дисциплин стали воспринимать разработку более серьезно.

Большое внимание Гамильтон уделяла тому, как совершаются ошибки, каким образом мы их допускаем.

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

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

Другой инженерный принцип, сформулированный в ранних работах Гамильтон, — идея безопасного сбоя. Она предполагает, что мы никогда не сможем закодировать каждый сценарий. Тогда каким же образом мы составляем код так, что наша система справляется с неожиданными сбоями и продолжает успешно работать? Известно, что именно благодаря тому, что Гамильтон реализовала эту необязательную идею, миссия «Аполлон-11» оказалась успешной и лунный модуль Eagle достиг поверхности Луны, хотя компьютер испытывал перегрузку во время посадки.

Во время спуска Нила Армстронга и Базза Олдрина на поверхность Луны астронавты обменивались данными с центром управления. Когда модуль LEM приблизился к поверхности Луны, компьютер передал сигналы 1201 и 1202. Астронавты спросили, следует ли продолжать снижение или прервать миссию.

НАСА колебалось, пока один из инженеров не прокричал «Продолжаем!», потому что понял, что случилось.

На «Аполлоне 11» каждый раз, когда возникали сигналы тревоги 1201 и 1202, компьютер перезагружался и перезапускал важные системы — управление двигателем спускаемого аппарата или дисплей и клавиатуру, чтобы экипаж знал, что происходит. Но не перезагружал все ошибочные запланированные задачи радара сближения. Ребята из центра управления полетами НАСА знали, — поскольку институт проводил масштабное тестирование перезапуска, — что миссия может продолжаться9.

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

Итак, Гамильтон и ее команда внедрили две ключевые черты инженерного мышления: эмпирические познание и открытие и привычку прогнозировать возможность ошибки.

Рабочее определение инженерии

Большинство словарных определений слова «инженерия» включает одинаковые слова и фразы: «использование математики», «эмпирические доказательства», «научные рассуждения», «с учетом экономических ограничений».

Я предлагаю такое определение: