Software: Ошибки и компромиссы при разработке ПО - Томаш Лелек - E-Book

Software: Ошибки и компромиссы при разработке ПО E-Book

Томаш Лелек

0,0

Beschreibung

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

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: 560

Veröffentlichungsjahr: 2024

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.



Томаш Лелек, Джон Скит
Software: Ошибки и компромиссы при разработке ПО

Переводчики Е. Матвеев, Е. Матвеев, Е. Матвеев, Е. Матвеев

Томаш Лелек, Джон Скит

Software: Ошибки и компромиссы при разработке ПО . — СПб.: Питер, 2023.

ISBN 978-5-4461-2320-9

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

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

Оглавление

Предисловие
Благодарности
О книге
Для кого эта книга
Структура книги
О коде
Форум liveBook
Об авторах
Иллюстрация на обложке
От издательства
Словарь паттернов проектирования
Глава 1. Введение
1.1. Последствия каждого решения и паттерна
1.2. Программные паттерны проектирования и почему они работают не всегда
1.3. Архитектурные паттерны проектирования и почему они работают не всегда
Итоги
Глава 2. Дублирование кода не всегда плохо: дублирование кода и гибкость
2.1. Общий код в кодовых базах и дублирование
2.2. Библиотеки и совместное использование кода в кодовых базах
2.3. Выделение кода в отдельный микросервис
2.4. Улучшение слабой связанности за счет дублирования кода
2.5. Проектирование API с наследованием для сокращения дублирования
Итоги
Глава 3. Исключения и другие паттерны обработки ошибок в коде
3.1. Иерархия исключений
3.2. Лучшие паттерны для обработки исключений в собственном коде
3.3. Антипаттерны в обработке исключений
3.4. Исключения из сторонних библиотек
3.5. Исключения в многопоточных средах
3.6. Функциональный подход к обработке ошибок с Try
3.7. Сравнение производительности кода обработки исключений
Итоги
Глава 4. Баланс между гибкостью и сложностью
4.1. Мощный, но не расширяемый API
4.2. Возможность предоставления собственной библиотеки метрик
4.3. Обеспечение расширяемости API с использованием перехватчиков
4.4. Обеспечение расширяемости API за счет использования прослушивателей
4.5. Анализ гибкости API и затраты на обслуживание
Итоги
Глава 5. Преждевременная оптимизация и оптимизация критического пути: решения, влияющие на производительность кода
5.1. Когда преждевременная оптимизация — зло
5.2. Критические пути в коде
5.3. Словарный сервис с потенциальным критическим путем
5.4. Обнаружение критического пути в коде
5.5. Повышение производительности критического пути
Итоги
Глава 6. Простота и затраты на обслуживание API
6.1. Базовая библиотека, используемая другими инструментами
6.2. Прямое предоставление настроек зависимой библиотеки
6.3. Абстрагирование настроек зависимой библиотеки
6.4. Добавление новой настройки для облачной клиентской библиотеки
6.5. Удаление настроек в облачной клиентской библиотеке
Итоги
Глава 7. Эффективная работа с датой и временем
7.1. Концепции представления даты и времени
7.2. Подготовка к работе с информацией о дате и времени
7.3. Реализация кода даты и времени
7.4. Граничные случаи
Итоги
Глава 8. Локальность данных и использование памяти
8.1. Что такое локальность данных?
8.2. Секционирование и разбиение данных
8.3. Соединение наборов больших данных из нескольких секций
8.4. Обработка данных: память и диск
8.5. Реализация соединений с использованием Apache Spark
Итоги
Глава 9. Сторонние библиотеки: используемые библиотеки становятся кодом
9.1. Импортирование библиотеки и ответственность за ее настройки: берегитесь значений по умолчанию
9.2. Модели параллельного выполнения и масштабируемость
9.3. Тестируемость
9.4. Зависимости сторонних библиотек
9.5. Выбор и обслуживание сторонних зависимостей
Итоги
Глава 10. Целостность и атомарность в распределенных системах
10.1. Источники данных с доставкой «не менее одного раза»
10.2. Наивная реализация дедупликации
10.3. Типичные ошибки при реализации дедупликации в распределенных системах
10.4. Обеспечение атомарности логики для предотвращения ситуации гонки
Итоги
Глава 11. Семантика доставки в распределенных системах
11.1. Архитектура событийно-управляемых приложений
11.2. Производители и потребители на базе Apache Kafka
11.3. Логика производителя
11.4. Код потребителя и разные семантики доставки
11.5. Использование гарантий доставки для обеспечения отказоустойчивости
Итоги
Глава 12. Управление версиями и совместимостью
12.1. Версионирование на абстрактном уровне
12.2. Версионирование для библиотек
12.3. Версионирование для сетевых API
12.4. Версионирование для хранилищ данных
Итоги
Глава 13. Современные тенденции разработки и затраты на сопровождение кода
13.1. Когда использовать фреймворки внедрения зависимостей
13.2. Когда применяется реактивное программирование
13.3. Когда применяется функциональное программирование
13.4. Отложенное и немедленное вычисление
Итоги
Рекомендуем прочитать

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

Джон посвящает написанные им главы всем программистам, которые хоть раз ломали голову над проблемой, возникшей из-за часовых поясов или ромбовидных зависимостей. (А это делало большинство разработчиков…)

Предисловие

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

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

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

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

Работа над книгой требует больших усилий. Тем не менее благодаря издательству Manning она стала настоящим удовольствием.

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

Я благодарю своего редактора в Manning Дуга Раддера (Doug Rudder). Спасибо за совместную работу — твои комментарии и обратная связь были бесценны. С твоей помощью я прокачал свои писательские навыки до нового уровня. Спасибо всем остальным сотрудникам Manning, которые участвовали в создании и продвижении книги. Это действительно была командная работа. Отдельное огромное спасибо выпускающему редактору Дейрдре Хайем (Deirdre Hiam); литературному редактору Кристиану Берку (Christian Berk); ревьюеру Михаэле Батинич (Mihaela Batinic) и корректору Джейсону Эверетту (Jason Everett).

Также хотелось бы поблагодарить рецензентов, которые не пожалели времени, чтобы прочитать мою рукопись на разных стадиях ее создания, и предоставили бесценную обратную связь — ваши предложения помогли мне улучшить книгу: Алекс Сез (Alex Saez), Александр Вейер (Alexander Weiher), Андрес Сакко (Andres Sacco), Эндрю Эленески (Andrew Eleneski), Энди Кирш (Andy Kirsch), Конор Редмонд (Conor Redmond), Косимо Атанаси (Cosimo Atanasi), Дэйв Корун (Dave Corun), Джордж Томас (George Thomas), Жиль Ячелини (Gilles Iachelini), Грегори Варгезе (Gregory Varghese), Хьюго Крус (Hugo Cruz), Иоханнес Вервийнен (Johannes Verwijnen), Джон Гатри (John Guthrie), Джон Генри Галино (John Henry Galino), Джонни Слос (Johnny Slos), Максим Прохоренко (Maksym Prokhorenko), Марк-Оливер Шееле (Marc-Oliver Scheele), Нельсон Гонсалес (Nelson González), Оливер Кортен (Oliver Korten), Паоло Брунасти (Paolo Brunasti), Рафаэль Авила Мартинес (Rafael Avila Martinez), Раджиш Моханан (Rajesh Mohanan), Роберт Траусмут (Robert Trausmuth), Роберто Касадеи (Roberto Casadei), Со Фай Фон (Sau Fai Fong), Шон Лам (Shawn Lam), Спенсер Маркс (Spencer Marks), Василь Борис (Vasile Boris), Винсент Делкойн (Vincent Delcoigne), Витош Дойнов (Vitosh Doynov), Уолтер Стоунбернер (Walter Stoneburner) и Уилл Прайс (Will Price).

Отдельное спасибо редактору-консультанту Джин Боярски (Jeanne Boyarsky) за подробный разбор текста с технической точки зрения.

Эта книга стала результатом всех профессиональных решений, которые принимал я и те, с кем я общался в ходе работы. Я встречал многих людей, которые сформировали меня как программиста и положительно повлияли на мою карьеру. Мне повезло познакомиться и работать с ними в начале карьеры. Хочу поблагодарить всех своих коллег из Schibsted, Allegro, DataStax и Dremio. Некоторые из них заслуживают особой благодарности:

Павел Волошин (Paweł Wołoszyn) — за то, что он превосходный университетский лектор, научивший меня тому, что программирование способно кардинально изменить мир.Анджей Гжесик (Andrzej Grzesik) — за то, что вдохновил меня на стремление к достижению амбициозных целей.Матеуш Квасьневский (Mateusz Kwasniewski) — за то, что разжег во мне иск­ру жажды к знаниям.Лукаш Банцеровский (Łukasz Bancerowski) — за то, что указал мне направление и сформировал мою карьеру в сфере JVM.Ярослав Палка (Jarosław Pałka) — за то, что поверил в меня и обеспечил пространство для экспериментов и обучения.Александр Дутра (Alexandre Dutra) — за то, что подавал пример и демонстрировал высочайшую рабочую этику.

— Томаш Лелек

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

— Джон Скит

О книге

Книга «Software: Ошибки и компромиссы при разработке ПО» была задумана как описание проблем, встречающихся в реальных системах. Мы постарались проанализировать каждую ситуацию в разных контекстах и рассмотреть все возможные компромиссы. Кроме того, в книге представлены некоторые неочевидные ошибки, способные значительно повлиять на системы в разных аспектах (не только с точки зрения правильности).

Для кого эта книга

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

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

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

В главе 1 представлен подход, используемый в книге для анализа компромиссов в определенном контексте. В ней приводятся примеры компромиссов на уровнях программной архитектуры, кода и контроля качества.Глава 2 показывает, что дублирование кода не всегда является антипаттерном. В ней рассматриваются различные архитектуры и анализируется их влияние на слабую связанность систем. Глава завершается вычислением затрат на координацию внутри команд и между ними по закону Амдала.В главе 3 описаны стратегии обработки аномальных ситуаций в коде. В ней разобраны сценарии использования как проверяемых, так и непроверяемых исключений. Вы научитесь разрабатывать стратегии обработки исключений для общедоступных API (библиотек). Наконец, в ней рассматриваются компромиссы между подходами обработки исключений, применяемыми в объектном и функциональном программировании.Глава 4 учит выдерживать баланс между сложностью кода и API. Она показывает, что эволюция кода в одном из направлений часто влияет на другие направления.Глава 5 объясняет, что преждевременная оптимизация не всегда плоха. С правильным инструментарием и определенными условиями SLA можно найти критический путь и оптимизировать его. Кроме того, она демонстрирует, что принцип Парето полезен, чтобы сконцентрировать усилия по оптимизации в нужной части системы.В главе 6 показано, как проектировать API с качественным UX. Она показывает, что удобство UX характеризует не только пользовательские, но и программные интерфейсы: REST API, средства командной строки и т.д. Однако глава также показывает, что за удобство UX приходится расплачиваться повышением затрат на обслуживание.В главе 7 рассматриваются болезненные вопросы обработки информации даты и времени. Если учесть, как часто данные содержат по крайней мере некоторые элементы даты и времени — например, дату рождения или временную метку записи в журнале, возможностей для возникновения ошибок более чем достаточно. С этими проблемами можно справиться, но они требуют особого внимания.Глава 8 объясняет, почему локальность данных играет важную роль в обработке больших данных. Она демонстрирует необходимость алгоритмов разбиения, обеспечивающих распределение данных и трафика.Глава 9 показывает, что используемые вами библиотеки становятся вашим кодом. В ней рассмотрены проблемы и компромиссы, которые необходимо учитывать при импортировании сторонней библиотеки в кодовую базу. Наконец, глава пытается ответить на вопрос, стоит ли импортировать библиотеку или лучше заново реализовать ее отдельные части.Глава 10 посвящена компромиссу между целостностью данных и атомарностью в распределенных системах. В ней анализируются возможные ситуации гонки в таких системах и влияние идемпотентности на способы проектирования систем.Глава 11 объясняет семантику доставки в распределенных системах. Она помогает понять семантику «не менее одного», «не более одного» и «фактически ровно один».В главе 12 вы узнаете, как программные системы, API и хранимые данные эволюционируют со временем и как при этом сохранять совместимость с другими системами.Глава 13 демонстрирует, что не всегда разумно гнаться за новейшими тенденциями в IT-отрасли. В ней анализируются некоторые популярные паттерны и фреймворки (такие, как реактивное программирование), а также обсуждается их применение в конкретных контекстах.

О коде

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

Во многих случаях оригинальная версия исходного кода переформатируется; добавляются разрывы строк и измененные отступы, чтобы код помещался на странице. Иногда даже этого оказывается недостаточно и в листинги включаются маркеры продолжения строк (). Также из исходного кода часто удаляются комментарии, если код описывается в тексте.

Исходный код в книге форматирован автоматизированным плагином в соответствии с рекомендациями Google по оформлению кода. Многие листинги снабжены примечаниями, выделяющими важные концепции. Каждая глава представлена отдельной папкой в репозитории. Для всего кода, использованного в книге, написаны многочисленные модульные и интеграционные тесты, обеспечивающие его качество. Не все тесты приводятся в листингах книги. Вы можете как запустить тесты, так и прочитать их код по отдельности, чтобы лучше понять конкретную часть логики. Все инструкции по импортированию и запуску примеров содержатся в файле README.md в репозитории.

Исполняемые фрагменты кода можно загрузить из версии liveBook (электронной) по адресу https://livebook.manning.com/book/software-mistakes-and-tradeoffs. Полный код примеров книги доступен для загрузки на сайте Manning по адресам https://www.manning.com/books/software-mistakes-and-tradeoffs и https://github.com/tomekl007/manning_software_mistakes_and_tradeoffs.

Форум liveBook

Приобретая книгу, вы получаете бесплатный доступ к liveBook, платформе Manning для чтения в интернете. С помощью эксклюзивных средств liveBook можно добавлять комментарии к книгам — глобально или к отдельным разделам/абзацам. Кроме того, можно делать заметки для себя, задавать технические вопросы и отвечать на них, получать помощь от автора и других пользователей. Чтобы получить доступ к форуму, перейдите по ссылке https://livebook.manning.com/book/software-mistakes-and-tradeoffs/discussion. Узнать больше о форумах Manning и правилах поведения на них можно на странице https://livebook.manning.com/discussion.

Manning соблюдает обязательство перед читателями по предоставлению площадки для содержательной дискуссии между читателями и между читателями и автором. Со стороны автора отсутствуют обязательства о конкретной доле участия, и его вклад в работу форума остается добровольным (и неоплачиваемым). Задавайте автору сложные вопросы, чтобы его интерес не потерялся! Форум и архивы предыдущих обсуждений будут доступны на веб-сайте издателя, пока книга продолжает издаваться.

Об авторах

Томаш Лелек

За свою карьеру разработчика Томаш имел дело с разными сервисами, архитектурами и языками программирования (прежде всего для JVM). У него есть реальный опыт работы с монолитными и микросервисными архитектурами. Томаш проектировал системы, обрабатывающие запросы десятков миллионов уникальных пользователей и сотни тысяч операций в секунду. В частности, он работал над следующими проектами:

Микросервисная архитектура с CQRS (на базе Apache Kafka).Автоматизация маркетинга и обработка потоков событий.Обработка больших данных в Apache Spark и Scala.

Сейчас Томаш работает в Dremio, где помогает создавать современные решения для хранения данных. До этого он работал в DataStax, где строил различные продукты для Cassandra Database. Он создавал инструменты для тысяч разработчиков, которые больше всего ценят проектирование API, производительность и удобство UX. Он внес свой вклад в разработку Java-Driver, Cassandra Quarkus, соединителя Cassandra-Kafka и Stargate.

Джон Скит

Джон — специалист по выстраиванию отношений с разработчиками в Google, в настоящее время работающий над библиотеками Google Cloud Client Libraries для .NET. Его вклад в сообщество с открытым кодом включает библиотеку даты и времени Noda Time для .NET (https://nodatime.org). Вероятнее всего, он известен благодаря своим публикациям на сайте Stack Overflow. Джон — автор книги «C# in Depth» (издательство Manning). Также он участвовал в работе над книгами «Groovy in Action» и «Real-World Functional Programming». Джон интересуется API даты/времени и версионированием — многим эти увлечения кажутся в лучшем случае необычными.

Иллюстрация на обложке

Иллюстрация под названием Groenlandaisse («Гренландка»), помещенная на обложку, взята из вышедшего в 1797 году каталога национальных костюмов, составленного Жаком Грассе де Сен-Совером. Каждая иллюстрация этого каталога тщательно прорисована и раскрашена от руки. В прежние времена по одежде человека можно было легко определить, где он живет и какова его профессия или положение. Manning отдает дань изобретательности и инициативности компьютерных технологий, используя для своих изданий обложки, демонстрирующие богатое вековое разнообразие региональных культур, оживающее на изображениях из собраний, подобных этому.

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

На момент сдачи книги в печать все приведенные в ней URL-ссылки работают, однако доступ к некоторым сайтам ограничен на территории РФ.

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

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

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

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

Словарь паттернов проектирования

Декоратор

Decorator

Наблюдатель

Observer

Одиночка

Singleton

Заместитель

Proxy

Прерыватель

Circuit Breaker

Прототип

Prototype

Стратегия

Strategy

Строитель

Builder

Фабрика

Factory