
В книге изложены приемы и методы, обязательные при грамотном объектно-ориентированном программировании. Следование приведенным паттернам проектирования защитит программу от ошибок, проблем с совместимостью, неожиданных и непонятных отказов, а также обеспечит модульность кода. Рассмотрены примеры на языке Java, легко адаптируемые для C#, пояснены приёмы тестирования, развития и адаптации кода с учётом меняющихся требований.
Книга адресована программистам на языках Java и C# и руководителям команд, практикующих объектно-ориентированное программирование.
Разница между хорошим и плохим кодом зачастую сводится к тому, насколько искусно в коде применяются паттерны и практики, принятые в сообществе разработчиков. В предлагаемой книге рассказано, как повысить производительность труда, пользуясь при программировании такими приёмами, которые обычно усваиваются только под тщательным руководством наставника и после многократного ревью кода.
На первый взгляд эта книга может напомнить другие пособия по «паттернам проектирования» для начинающих, но в некоторых важных отношениях выделяется на их фоне. В частности, здесь рассказано:
- Как писать код, который сложно использовать ненадлежащим образом
- Как правильно организовать обработку ошибок в приложениях
- Как обеспечить модульность кода, оптимизировав его для повторного использования
- Как при необходимости переводить примеры кода с Java на C#
- Как правильно организовать тестирование кода и внедрение зависимостей
В наибольшей степени книга подойдёт разработчикам, специализирующимся на Java и C#, но также пригодится более широкому кругу программистов, желающих повысить качество объектно-ориентированного кода.
Отзывы
Практичная и информативная книга, которая поможет вам создавать высококачественный и эффективный код.
Кристофер Виллануэва, независимый консультант
Умная, хорошо написанная, практичная книга о том, как писать хороший код, который удобно поддерживать.
Хоули Уолдмен, консультант
Я преподаватель программирования, и мне понравилось, что рассматривает и чему учит эта книга. Она становится в один ряд с такими шедеврами, как «Совершенный код» Стива Макконнелла. В ней в мельчайших деталях показано, каким должен быть «хороший код», почему для приобретения мастерства нужно не только знать, что и как пишется, но и уметь думать как программист.
Ховард Дайнер, отзыв с Amazon
Книгу “Хороший код, плохой код” можно купить со скидкой в интернет-магазине издательства “БХВ“.
Глава 1. Введение………………………………………… 7
1.1. Для кого эта книга……………………………………….. 7
1.2. Что понадобится…………………………………………. 7
1.3. Первая программа………………………………………. 8
1.4. Задания…………………………………………………… 11
Глава 2. Переменные…………………………………. 11
2.1. Типы переменных……………………………………… 11
2.2. Соглашение об именовании переменных…………. 13
2.3. Типы данных……………………………………………. 13
2.4. Значения по умолчанию………………………………. 14
2.5. Литералы………………………………………………… 15
2.6. Целочисленные литералы……………………………. 15
2.7. Литералы с плавающей точкой……………………… 16
2.8. Символьные и строковые литералы……………….. 17
2.9. Другие литералы……………………………………….. 18
2.10. Массивы……………………………………………….. 19
2.11. Задания…………………………………………………. 20
Глава 3. Операции……………………………………… 21
3.1. Операция присваивания……………………………… 21
3.2. Преобразование примитивных типов………………. 22
3.3. Расширяющее преобразование примитивов……… 22
3.4. Сужающее преобразование примитивов………….. 23
3.5. Арифметические операции…………………………… 24
3.6. Унарные операции…………………………………….. 26
3.7. Отличие постфиксного и префиксного инкремента и декремента 27
3.8. Операции сравнения………………………………….. 28
3.9. Логические И и ИЛИ…………………………………… 29
3.10. Операция instanceof…………………………………. 29
3.11. Тернарная операция…………………………………. 31
3.12. Битовые операции……………………………………. 31
3.13. Присвоение с выполнением другой операции….. 32
3.14. Приоритеты операций……………………………….. 33
3.15. Задания…………………………………………………. 34
Глава 4. Выражения, инструкции и блоки……. 35
4.1. Операторы управления порядком выполнения….. 36
4.2. Операторы if-then и if-then-else……………………… 37
4.3. Оператор switch………………………………………… 39
4.4. Оператор while………………………………………….. 43
4.5. Оператор do-while……………………………………… 45
4.6. Оператор for…………………………………………….. 45
4.7. Оператор break…………………………………………. 47
4.8. Оператор continue……………………………………… 48
4.9. Оператор return…………………………………………. 49
4.10. Задания…………………………………………………. 50
Глава 5. Классы и объекты………………………… 50
5.1. Классы……………………………………………………. 50
5.2. Поля………………………………………………………. 51
5.3. Объявление методов………………………………….. 53
5.4. Конструкторы……………………………………………. 56
5.5. Передача параметров…………………………………. 58
5.6. Сборка мусора………………………………………….. 61
5.7. Ключевое слово this…………………………………… 61
5.8. Ключевое слово static………………………………… 63
5.9. Ключевое слово final………………………………….. 64
5.10. Инициализация полей……………………………….. 66
5.11. Задания…………………………………………………. 68
Глава 6. Аннотации…………………………………….. 69
6.1. Объявление аннотаций……………………………….. 69
6.2. Предопределенные аннотации………………………. 72
6.3. Мета-аннотации………………………………………… 73
6.4. Задания…………………………………………………… 75
Глава 7. Вложенные классы
и лямбда-выражения………………………………….. 75
7.1. Что такое вложенные классы……………………….. 75
7.2. Для чего использовать вложенные классы………. 76
7.3. Статические вложенные классы……………………. 77
7.4. Внутренние классы……………………………………. 79
7.5. Внутренний класс, являющийся нестатическим членом класса 80
7.6. Локальные классы…………………………………….. 81
7.7. Анонимные классы…………………………………….. 82
7.8. Затенение переменных……………………………….. 84
7.9. Лямбда-выражения…………………………………….. 85
7.10. Ссылки на методы……………………………………. 89
7.11. Когда использовать вложенные классы, локальные классы, анонимные классы
и лямбда-выражения……………………………………… 91
7.12. Задания…………………………………………………. 92
Глава 8. Интерфейсы…………………………………. 93
8.1. Теория……………………………………………………. 93
8.2. Задания…………………………………………………… 99
Глава 9. Наследование……………………………….. 99
9.1. Введение…………………………………………………. 99
9.2. Приведение типов……………………………………. 101
9.3. Переопределение (overriding) и скрытие (hiding) методов 102
9.4. Использование ключевого слова super………….. 106
9.5. Общий предок Object и его методы……………….. 109
9.6. Ключевое слово final и неизменяемые классы…. 112
9.7. Абстрактные методы и классы…………………….. 112
9.8. Задания…………………………………………………. 113
Глава 10. Пакеты……………………………………… 114
10.1. Теория…………………………………………………. 114
10.2. Задания……………………………………………….. 118
Глава 11. Перечисления……………………………. 118
11.1. Теория…………………………………………………. 118
11.2. Задания……………………………………………….. 123
Глава 12. Записи………………………………………. 123
12.1. Теория…………………………………………………. 123
12.2. Задания……………………………………………….. 125
Глава 13. Числа………………………………………… 126
13.1. Введение……………………………………………… 126
13.2. BigInteger……………………………………………… 128
13.3. BigDecimal……………………………………………. 130
13.4. Math……………………………………………………. 132
13.5. Задания……………………………………………….. 133
Глава 14. Строки………………………………………. 134
14.1. Класс String…………………………………………… 134
14.2. Методы класса String………………………………. 140
14.3. StringBuilder и StringBuffer…………………………. 143
14.4. Задания……………………………………………….. 145
Глава 15. Автоупаковка и распаковка……….. 146
15.1. Теория…………………………………………………. 146
15.2. Задания……………………………………………….. 148
Глава 16. Optional…………………………………….. 149
16.1. Теория…………………………………………………. 149
16.2. Задания……………………………………………….. 154
Глава 17. Модули……………………………………… 154
17.1. Теория…………………………………………………. 154
17.2. Задания……………………………………………….. 159
Глава 18. Обобщения………………………………… 160
18.1. Введение……………………………………………… 160
18.2. Класс Lair……………………………………………… 160
18.3. Обобщенная версия класса Lair…………………. 161
18.4. Соглашение об именовании переменных типа.. 162
18.5. Создание экземпляра обобщенного типа и обращение к нему 162
18.6. Бриллиантовая операция (Diamond operator)…. 163
18.7. Несколько параметров типа………………………. 164
18.8. Сырой тип (Raw type)……………………………… 164
18.9. Сообщения об ошибках “unchecked”……………. 165
18.10. Обобщенные методы……………………………… 166
18.11. Ограниченные параметры типа…………………. 167
18.12. Обобщения, наследование и дочерние типы… 169
18.13. Выведение типов………………………………….. 171
18.14. Выведение типов и обобщенные методы…….. 172
18.15. Выведение типов и создание экземпляра обобщенного класса 173
18.16. Выведение типа и обобщенные конструкторы обобщенных и необобщенных классов 174
18.17. Целевые типы……………………………………… 175
18.18. Подстановочный символ (wildcard)……………. 176
18.19. Подстановочный символ, ограниченный сверху (Upper bounded wildcard) 176
18.20. Неограниченный подстановочный символ (Unbounded wildcard) 177
18.21. Подстановочные символы и дочерние типы… 179
18.22. Захват символа подстановки (Wildcard Capture) и вспомогательные методы 180
18.23. Руководство по использованию подстановочного символа 182
18.24. Стирание типа (Type Erasure)…………………… 184
18.25. Стирание типа в обобщенных типах…………… 184
18.26. Стирание типа в обобщенных методах……….. 185
18.27. Получение аргумента типа родительского класса 185
18.28. Влияние стирания типа и методы-мосты
(bridge methods)………………………………………….. 186
18.29. Методы-мосты (Bridge Methods)……………….. 187
18.30. Загрязнение кучи (Heap pollution)………………. 188
18.31. Подавление предупреждений для методов с произвольным количеством параметров с нематериализуемыми формальными
параметрами………………………………………………. 191
18.32. Ограничения обобщений…………………………. 192
18.33. Задания………………………………………………. 195
Глава 19. Исключения………………………………. 195
19.1. Введение……………………………………………… 195
19.2. Перехватывание и обработка исключений…….. 197
19.3. Указание типов исключений, бросаемых методом 202
19.4. Как бросить исключение…………………………… 203
19.5. Цепочки исключений……………………………….. 203
19.6. Создание своих объектов-исключений…………. 204
19.7. Преимущества исключений……………………….. 205
19.8. Задания……………………………………………….. 205
Глава 20. Потоки ввода/вывода………………… 206
20.1. Введение……………………………………………… 206
20.2. Потоки байт…………………………………………… 206
20.3. InputStream…………………………………………… 206
20.4. OutputStream…………………………………………. 208
20.5. FileInputStream и FileOutputStream……………… 209
20.6. ByteArrayInputStream и ByteArrayOutputStream. 210
20.7. FilterInputStream и FilterOutputStream………….. 210
20.8. DataInputStream и DataOutputStream…………… 210
20.9. BufferedInputStream и BufferedOutputStream….. 210
20.10. PipedInputStream и PipedOutputStream……….. 211
20.11. ObjectInputStream и ObjectOutputStream…….. 211
20.12. Потоки символов…………………………………… 211
20.13. Scanner и PrintStream…………………………….. 212
20.14. Задания………………………………………………. 212
Глава 21. Сериализация……………………………. 213
21.1. Теория…………………………………………………. 213
21.2. Задания……………………………………………….. 216
Глава 22. Файлы (NIO.2)……………………………. 216
22.1. Path…………………………………………………….. 216
22.2. Что такое Glob?……………………………………… 219
22.3. Класс Files……………………………………………. 219
22.4. Проверка существования файла или каталога.. 219
22.5. Проверка прав доступа к файлу или каталогу… 220
22.6. Один и тот же файл…………………………………. 220
22.7. Удаление файла или каталога……………………. 220
22.8. Копирование файла или каталога………………… 221
22.9. Перемещение файла или каталога………………. 221
22.10. Управление метаданными……………………….. 221
22.11. OpenOption………………………………………….. 223
22.12. Наиболее часто используемые методы для небольших файлов 224
22.13. Буферизированный ввод и вывод в текстовые файлы 225
22.14. Небуферизированный ввод и вывод………….. 225
22.15. Создание файлов………………………………….. 225
22.16. Создание временных файлов…………………… 225
22.17. Java NIO.2 Channels……………………………… 226
22.18. Перечисление корневых каталогов файловой системы 228
22.19. Создание каталога…………………………………. 228
22.20. Создание временного каталога…………………. 228
22.21. Перечисление содержимого каталога…………. 229
22.22. Символические и другие ссылки……………….. 231
22.23. Создание символических ссылок………………. 231
22.24. Создание жестких ссылок……………………….. 231
22.25. Определение символической ссылки…………. 232
22.26. Нахождение цели ссылки………………………… 232
22.27. Обход дерева файлов с FileVisitor…………….. 232
22.28. Поиск файлов………………………………………. 235
22.29. Подписываемся на изменения в каталоге……. 235
22.30. Задания………………………………………………. 237
Глава 23. Многопоточность……………………….. 237
23.1. Класс Thread…………………………………………. 237
23.2. Синхронизация………………………………………. 243
23.3. Вмешательство в поток (thread interference)….. 243
23.4. Ошибки согласованности памяти (memory consistency errors) 245
23.5. Синхронизированные (synchronized) методы…. 245
23.6. Внутренние мониторы и синхронизация……….. 247
23.7. Атомарный доступ………………………………….. 248
23.8. Атомарные переменные…………………………… 249
23.9. Взаимная блокировка (Deadlock)………………… 251
23.10. Голодание (starvation)…………………………….. 253
23.11. Активная блокировка (livelock)………………….. 253
23.12. Защищенные блокировки (guarded blocks)……. 253
23.13. Неизменяемые объекты (immutable objects)… 257
23.14. Объекты Lock………………………………………. 258
23.15. Executors……………………………………………. 259
23.16. CompletableFuture…………………………………. 260
23.17. Пулы потоков………………………………………. 263
23.18. Fork/Join Framework………………………………. 264
23.19. Java Memory Model……………………………….. 266
23.20. Задания………………………………………………. 270
Глава 24. Настройки и окружение……………… 270
24.1. Properties……………………………………………… 270
24.2. Аргументы командной строки…………………….. 273
24.3. Переменные окружения……………………………. 274
24.4. Методы класса System……………………………. 275
24.5. Переменная CLASSPATH…………………………. 275
24.6. Задания……………………………………………….. 275
Глава 25. Регулярные выражения…………….. 276
25.1. Теория…………………………………………………. 276
25.2. Задания……………………………………………….. 277
Глава 26. Коллекции…………………………………. 278
26.1. Введение……………………………………………… 278
26.2. Интерфейс Collection………………………………. 278
26.3. Интерфейс Set………………………………………. 280
26.4. Интерфейс List………………………………………. 281
26.5. Интерфейс Queue…………………………………… 283
26.6. Интерфейс Deque…………………………………… 284
26.7. Интерфейс Map……………………………………… 285
26.8. Интерфейс ConcurrentMap………………………… 286
26.9. Класс Dictionary и его наследник Hashtable…… 287
26.10. Сортировка объектов……………………………… 287
26.11. Интерфейс SortedSet……………………………… 292
26.12. Интерфейс SortedMap……………………………. 294
26.13. Другие реализации интерфейсов коллекций…. 295
26.14. Java Stream API……………………………………. 296
26.15. Алгоритмы…………………………………………… 303
26.16. Задания………………………………………………. 304
Глава 27. Дата и время……………………………… 305
27.1. Введение……………………………………………… 305
27.2. Класс Date……………………………………………. 305
27.3. Класс Calendar………………………………………. 306
27.4. Пакет java.time………………………………………. 308
27.5. Перечисление DayOfWeek……………………….. 308
27.6. Перечисление Month……………………………….. 309
27.7. Класс LocalDate……………………………………… 311
27.8. Класс LocalTime…………………………………….. 311
27.9. Класс LocalDateTime……………………………….. 311
27.10. Класс YearMonth…………………………………… 312
27.11. Класс MonthDay……………………………………. 313
27.12. Класс Year…………………………………………… 313
27.13. Классы ZoneId и ZoneOffset…………………….. 313
27.14. Класс ZonedDateTime…………………………….. 315
27.15. Класс OffsetDateTime…………………………….. 315
27.16. Класс OffsetTime………………………………….. 316
27.17. Класс Instant……………………………………….. 316
27.18. Форматирование и преобразование из строки. 317
27.19. Интерфейс TemporalAdjuster……………………. 318
27.20. Интерфейс TemporalQuery………………………. 319
27.21. Класс Duration……………………………………… 319
27.22. Перечисление ChronoUnit……………………….. 320
27.23. Класс Period………………………………………… 320
27.24. Класс Clock…………………………………………. 321
27.25. Задания………………………………………………. 321
Глава 28. Форматирование и парсинг………… 322
28.1. Введение……………………………………………… 322
28.2. Класс NumberFormat……………………………….. 323
28.3. Класс DecimalFormat………………………………. 324
28.4. Класс DateFormat…………………………………… 325
28.5. Класс DateTimeFormatter…………………………. 326
28.6. Класс SimpleDateFormat…………………………… 326
28.7. Класс PrintStream…………………………………… 328
28.8. Класс Formatter……………………………………… 328
28.9. Класс Scanner……………………………………….. 333
28.10. Задания………………………………………………. 335
Глава 29. Работа с консолью…………………….. 336
29.1. Теория…………………………………………………. 336
29.2. Задание……………………………………………….. 338
Глава 30. Локализация……………………………… 339
30.1. Теория…………………………………………………. 339
30.2. Задание……………………………………………….. 341
Глава 31. Пример сервиса со Spring………….. 342
31.1. Что за сервис мы напишем……………………….. 342
31.2. Spring Initializr………………………………………… 343
31.3. Разбор сгенерированного скелета приложения.. 346
31.4. Добавление конечных точек………………………. 349
31.5. Слой бизнес-сервисов……………………………… 351
31.6. Работа с базой данных…………………………….. 357
31.7. Вызов методов с Postman………………………… 360
31.8. Docker…………………………………………………. 360
31.9. Kubernetes……………………………………………. 363
31.10. Задания………………………………………………. 366
Глава 32. Заключение……………………………….. 367
Том Лонг – программист корпорации Google, техлид. Наряду с решением производственных задач постоянно обучает начинающих программистов секретам профессионального мастерства.
-
Хороший код, плохой код
1125 ₽
956 ₽