Стильный Java. Код, который работает всегда и везде - Марко Фаэлла - E-Book

Стильный Java. Код, который работает всегда и везде E-Book

Марко Фаэлла

0,0

Beschreibung

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

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

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.



Марко Фаэлла
Стильный Java. Код, который работает всегда и везде
2021

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

Литературные редакторы Н. Викторова, А. Руденко

Художники В. Мостипан, А. Руденко

Корректоры Н. Викторова, М. Молчанова (Котова)

Верстка Л. Егорова

Марко Фаэлла

Стильный Java. Код, который работает всегда и везде. — СПб.: Питер, 2021.

ISBN 978-5-4461-1739-0

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

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

Оглавление

Предисловие
Введение
Благодарности
О книге
Об авторе
Об обложке
От издательства
Часть I. Отправная точка
Глава 1. Свойства кода и постановка задачи
1.1. Свойства кода
1.2. Преимущественно внешние свойства
1.3. Преимущественно внутренние свойства кода
1.4. Взаимодействие свойств кода
1.5. Специфичные свойства
1.6. Сквозной пример: система резервуаров для воды
1.7. Модель данных и представления
1.8. Hello, резервуары! [Novice]
Итоги
Дополнительная литература
Глава 2. Эталонная реализация
2.1. Код [Reference]
2.2. Требования к памяти
2.3. Временная сложность
2.4. Применим изученное
Итоги
Ответы на вопросы и упражнения
Дополнительная литература
Часть II. Свойства программного кода
Глава 3. Жажда скорости: эффективность по времени
3.1. Добавление воды с постоянным временем [Speed1]
3.2. Добавление соединений за постоянное время [Speed2]
3.3. Лучший баланс: алгоритмы поиска объединений [Speed3]
3.4. Сравнение реализаций
3.5. А теперь совсем другое
3.6. Реальные сценарии использования
3.7. Применим изученное
Итоги
Ответы на вопросы и упражнения
Дополнительная литература
Глава 4. Эффективность по затратам памяти
4.1. Первые шаги [Memory1]
4.2. Простые массивы
4.3. Отказ от объектов [Memory3]
4.4. Черная дыра [Memory4]
4.5. Баланс затрат памяти и времени
4.6. А теперь совсем другое
4.7. Реальные сценарии использования
4.8. Применим изученное
Итоги
Ответы на вопросы и упражнения
Дополнительная литература
Глава 5. Надежность за счет мониторинга
5.1. Контрактное проектирование
5.2. Контрактное проектирование резервуаров
5.3. Резервуары, проверяющие свои контракты [Contracts]
5.4. Резервуары, проверяющие свои инварианты [Invariants]
5.5. А теперь совсем другое
5.6. Реальные сценарии использования
5.7. Применим изученное
Итоги
Ответы на вопросы и упражнения
Дополнительная литература
Глава 6. Надежность за счет тестирования
6.1. Основные понятия тестирования
6.2. Тестирование резервуаров [UnitTests]
6.3. Тестируемость [Testable]
6.4. А теперь совсем другое
6.5. Реальные сценарии использования
6.6. Применим изученное
Итоги
Ответы на вопросы и упражнения
Дополнительная литература
Глава 7. Удобочитаемость
7.1. Разный взгляд на удобочитаемость
7.2. Структурные факторы удобочитаемости
7.3. Внешние факторы удобочитаемости
7.4. Код [Readable]
7.5. Напоследок об удобочитаемости
7.6. А теперь совсем другое
7.7. Реальные сценарии использования
7.8. Применим изученное
Итоги
Ответы на вопросы и упражнения
Дополнительная литература
Глава 8. Потокобезопасность
8.1. Проблемы потокобезопасности
8.2. Взаимоблокировки
8.3. Потокобезопасные резервуары [ThreadSafe]
8.4. Неизменяемость
8.5. А теперь совсем другое
8.6. Реальные сценарии использования
8.7. Применим изученное
Итоги
Ответы на вопросы и упражнения
Дополнительная литература
Глава 9. Повторное использование
9.1. Определение границ
9.2. Общая структура
9.3. Обобщенная реализация резервуара
9.4. Общие соображения
9.5. Использование готового кода [Generic]
9.6. Посты в соцсетях
9.7. А теперь совсем другое
9.8. Реальные сценарии использования
9.9. Применим изученное
Итоги
Ответы на вопросы и упражнения
Дополнительная литература
Приложения
Приложение А. Программный гольф: компактность
A.1. Самая короткая программа, которая у меня получилась [Golfing]
Дополнительная литература
Приложение Б. Финальная версия класса для резервуара с водой
Б.1. Улучшения удобочитаемости
Б.2. Улучшения надежности
Рекомендуем прочитать

Предисловие

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

В январе 2018 года я получил сообщение от Марко Фаэллы — профессора Неапольского университета, с которым я уже встречался в Калифорнийском университете в Санта-Крус. Он попросил совета относительно проекта книги. Более того, он уже написал несколько глав! То, что я увидел, мне понравилось. Я похвалил работу автора и внес несколько предложений. На этом общение прервалось. Меня это не удивило. Один из редакторов сказал мне, что он знал великое множество людей, которые начинали писать книгу… и лишь немногих, кто ее дописал.

В апреле 2019 года я получил новое сообщение — книга готовилась к печати в издательстве Manning и выглядела просто отлично. В августе Марко попросил меня написать предисловие, что я и делаю с огромным удовольствием.

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

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

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

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

Кей Хорстманн, Автор «Java»1, «Java / Scala / JavaScript for the Impatient»  и многих других книг для начинающих и опытных программистов

1Хорстманн К.С. Java / Пер. с англ. И.В. Берштейна. 11-е изд. — М.; СПб.: Диалектика, 2020. — (Серия «Библиотека профессионала»)

Введение

Я хотел назвать книгу «Java: упражнения в стиле». Но умные люди из издательства Manning помогли мне выбрать более яркое и запоминающееся название2. Дело в том, что в работе «Упражнения в стиле» французский писатель Раймон Кено записал одну простую историю в девяносто девяти стилистических вариантах.

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

В этой книге я освещаю широкий спектр проблем и решений, которые необходимо учитывать (или по крайней мере знать об их существовании) при написании кода. Предложенная задача тривиальна: создать класс резервуаров, которые можно соединять трубами и наполнять водой. С резервуарами взаимодействуют клиенты: добавляют или удаляют воду, устанавливают новые трубы. В восемнадцати реализациях этой задачи я постараюсь довести до максимума разные показатели кода: скорость выполнения, удобочитаемость и др. Это не будет сухой последовательностью фрагментов кода. Каждый раз, когда того потребует контекст, я затрону специализированные темы computer science (структуры данных, теорию сложности, амортизированную сложность), Java-программирования (синхронизацию программных потоков и модель памяти Java), методологии разработки (методологию контрактного проектирования и приемы тестирования). Я покажу, что даже простой пример при глубоком анализе оказывается связанным с огромной сетью тем, знание которых помогает писать более качественный код.

Дополнительная литература

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

• Raymond Queneau. Exercises in Style (New Directions, 2013).

Образец «упражнений в стиле», написанный на французском языке в 1947 году.

• Cristina Videira Lopes. Exercises in Programming Style (CRC, 2014).

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

• Matt Madden. 99 Ways to Tell a Story: Exercises in Style (Jonathan Cape, 2006).

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

2 Издательство «Питер» не смогло в полной мере пойти навстречу автору, но постаралось приблизить название русского издания к изначальной задумке. — Примеч. ред.

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

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

Я изучал Java по книгам Кея и много лет рекомендовал их студентам. Для меня большая честь, что он любезно согласился написать предисловие.

Благодарю всех рецензентов: Адитья Каушик (Aditya Kaushik), Александрос Кофудакис (Alexandros Koufoudakis), Бонни Бэйли (Bonnie Bailey), Элио Сальваторе (Elio Salvatore), Флавио Диез (Flavio Diez), Фостер Хейнс (Foster Haines), Грегори Решетняк (Gregory Reshetniak), Хессам Шафий Мокаддам (Hessam Shafiei Moqaddam), Ирфан Улла (Irfan Ullah), Джейкоб Ромеро (Jacob Romero), Джон Гатри (John Guthrie), Хуан Дж. Дурилло (Juan J. Durillo), Кимберли Уинстон-Джексон (Kimberly Winston-Jackson), Михал Амброзиевич (Michal Ambroziewicz), Серж Саймон (Serge Simon), Стивен Парр (Steven Parr), Торстен Вебер (Thorsten Weber) и Трэвис Нелсо (Travis Nelso) — ваши предложения помогли улучшить книгу.

Моя страсть к программированию началась в период, когда отец учил меня — любознательного восьмилетку — рисовать круг при помощи цикла for и двух таинственных заклинаний, которые назывались sin и cos. Grazie!

О книге

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

Схема на с. 12 связывает содержимое книги с широким спектром знаний, необходимых профессиональному разработчику. Изучение Java требует знакомства с классами, методами, полями и т.д. (здесь база не рассматривается). Далее освоение языка идет по трем путям:

• Путь языка программирования — изучение расширенных возможностей языка (таких, как обобщения и многопоточность).

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

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

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

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

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

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

• Разработчики с пробелами в теоретической подготовке или подготовкой в другой области (отличной от computer science) найдут здесь обзор теоретических и практических методов и компромиссов, связанных с нетривиальными задачами программирования.

• Студенты и специалисты computer science найдут в книге объединяющий практический сценарий для разных учебных дисциплин. Таким образом, книга дополнит учебники и другие материалы по программированию.

В обоих случаях извлечь максимальную пользу из книги помогут знания:

• основных концепций программирования (итераций, рекурсии и т.д.);

• основных концепций объектно-ориентированного программирования (инкапсуляции, наследования и т.д.);

• средств языка Java среднего уровня (обобщений, стандартных коллекций и базовой многопоточности: создания потоков, применения ключевого слова synchronized и т.д.).

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

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

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

Глава 2. Подробное описание эталонной реализации, обеспечивающей хороший баланс разных свойств.

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

Глава 4. Проведем эксперименты с эффективностью по затратам памяти и увидим, что по сравнению с эталонной реализацией затраты памяти сокращаются более чем на 50 % при использовании объектов и на 90 % — при отказе от использования отдельного объекта для каждого резервуара.

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

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

Глава 7. Произведем рефакторинг эталонной реализации для применения рекомендуемых методов создания чистого самодокументируемого кода.

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

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

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

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

Сетевой репозиторий

Весь код, представленный в книге, доступен в открытом сетевом репозитории (https://bitbucket.org/mfaella/exercisesinstyle). Основная часть кода состоит из разных версий класса Container. Каждой версии назначено условное имя, соответствующее имени пакета. Например, первая версия представлена в разделе 1.8 под именем Novice. В репозитории соответствующий класс называется eis.chapter1.novice.Container. В таблице в приложении Б перечислены основные классы и их характеристики.

Код примеров этой книги также доступен для загрузки на веб-сайте Manning по адресу: https://www.manning.com/books/seriously-good-software.

Почему Java? Какая версия Java?

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

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

Принципы, которые я излагаю в книге, так же хорошо работают на других языках. Чем ближе ваш язык программирования к Java (например, к нему близок C#), тем больше материала из книги вы сможете позаимствовать без изменений. Более того, в книге часто встречаются примечания для C#, в которых подчеркиваются различия в языках, связанные с материалом текущей главы.

В сетевом репозитории книги хранится код, 99 % которого написано на Java 8. В нескольких его частях использованы дополнения из Java 9 (например, возможность конструирования списка статическим методом List.of).

Форум для обсуждения книги

Приобретая книгу, вы получаете бесплатный доступ к закрытому веб-форуму Manning, на котором можно публиковать комментарии к книге, задавать технические вопросы и получать помощь от автора и других пользователей. Для доступа к форуму откройте страницу https://livebook.manning.com/#!/book/seriously-good-software/discussion. За информацией о форумах Manning и правилах поведения обращайтесь по адресу https://livebook.manning.com/#!/discussion.

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

Об авторе

Марко Фаэлла — преподаватель computer science в Неаполитанском университете имени Фридриха II (Италия). Помимо академических исследований в области computer science Марко увлеченно занимается преподаванием и программированием. Последние 13 лет он ведет курсы программирования повышенной сложности, а также является автором учебника для желающих получить сертификат Java-раз­работчика и видеокурса по потокам в языке Java.

Об обложке

Иллюстрация, помещенная на обложку второго издания книги, называется Homme Tscheremiss («черемис» — представитель народа, живущего неподалеку от современной Финляндии), была позаимствована из изданного в 1797 г. каталога национальных костюмов Жака Грассе де Сен-Совера (1757–1810) «Costumes de Differents Pays». Каждая иллюстрация красиво нарисована и раскрашена от руки. Иллюстрации из каталога Грассе де Сен-Совера напоминают о культурных различиях между городами и весями мира, имевших место почти двести лет назад. Люди, проживавшие в изолированных друг от друга регионах, говорили на разных языках и диалектах. По одежде человека можно было определить, в каком городе, поселке или поселении он проживает.

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

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

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

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

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

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

Часть I. Отправная точка

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

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