Незаменимые практические советы по написанию кода в устойчивом темпе и по управлению сложностью, из-за которой проекты часто выходят из-под контроля. В книге описываются методы и процессы, позволяющие решать ключевые вопросы: от создания чек-листов до организации командной работы, от инкапсуляции до декомпозиции, от проектирования API до модульного тестирования. Автор иллюстрирует свои выводы фрагментами кода, взятыми из готового проекта. Написанные на языке C#, они будут понятны всем, кто использует любой объектно-ориентированный язык, включая Java, C++ и TypeScript. Для более глубокого изучения материала вы можете загрузить весь код и подробные комментарии к коммитам.
Author(s): Марк Симан
Series: Библиотека программиста
Edition: 1
Publisher: Питер
Year: 2023
Language: Russian
Commentary: Publisher's PDF
Pages: 400
City: СПб.
Tags: Software Engineering; Security; Heuristics; Best Practices; Troubleshooting; API Design; Refactoring; Unit Testing; Git; Software Architecture; Complexity; Performance; Teamwork; Code Review; Monolithic Architecture; Encapsulation; Domain Modeling; Cyclomatic Complexity; Pair Programming; Checklist; Code Rot; Sustainability; Separation of Concerns; Rhythm; C#
Предисловие Роберта Мартина
Введение
Для кого эта книга
Исходные требования
Примечание для архитекторов ПО
Структура книги
О стиле кода
Типизировать явно или неявно
Примеры кода
Примечание к библиографии
О моих книгах
Благодарности
От издательства
Об авторе
I
Развитие
1
Искусство или наука?
1.1. Строительство здания
1.1.1. Проблема проекта
1.1.2. Этапы разработки
1.1.3. Зависимости
1.2. Возделывание сада
1.2.1. Что заставляет сад расти?
1.3. С точки зрения инженерии
1.3.1. Программирование как ремесло
1.3.2. Эвристика
1.3.3 Ранние представления о разработке ПО
1.3.4. Становление и развитие программной инженерии
1.4. Заключение
2
Чек-листы: история, виды, преимущества
2.1. Как ничего не забыть
2.2. Чек-лист для новой кодовой базы
2.2.1. Использовать GIT
2.2.2. Автоматизировать сборку
2.2.3. Включить все сообщения об ошибках
2.3. Добавление проверок в существующие кодовые базы
2.3.1. Постепенное улучшение
2.3.2. «Взломайте» свою организацию
2.4. Заключение
3
Преодоление трудностей
3.1. Цель
3.1.1. Надежность
3.1.2. Ценность
3.2. Почему программировать так сложно?
3.2.1. Аналогия с мозгом
3.2.2. Код больше читается, чем пишется
3.2.3. Удобочитаемость
3.2.4. Интеллектуальный труд
3.3. Навстречу программной инженерии
3.3.1. Связь с computer science
3.3.2. Гуманный код
3.4. Заключение
4
Вертикальный срез
4.1. Начните с рабочего ПО
4.1.1. От поступления данных до их сохранения
4.1.2. Минимальный вертикальный срез
4.2. «Ходячий скелет»
4.2.1. Характеризационные тесты
4.2.2. Паттерн AAA (Arrange-Act-Assert)
4.2.3. Модерация статического анализа
4.3. Модель тестирования «от общего к частному» (оutside-in)
4.3.1. Получение данных JSON
4.3.2. Размещение бронирования
4.3.3. Модульное тестирование
4.3.4. DTO и модель предметной области (доменная модель)
4.3.5. Fake Object или фиктивный объект
4.3.6. Интерфейс Repository
4.3.7. Работа с интерфейсом Repository
4.3.8. Настройка зависимостей
4.4. Завершение среза
4.4.1. Схема
4.4.2. Репозиторий SQL
4.4.3. Конфигурация базы данных
4.4.4. Дымовой тест или smoke-тестирование
4.4.5. Граничный тест с фиктивной базой данных
4.5. Заключение
5
Инкапсуляция
5.1. Сохранение данных
5.1.1. Предпосылки приоритета трансформации (TPP)
5.1.2. Параметризированные тесты
5.1.3. Копирование данных DTO в модель предметной области
5.2. Валидация
5.2.1. Невалидные данные
5.2.2. Цикл «красный, зеленый, рефакторинг»
5.2.3. Натуральные числа
5.2.4. Закон Постела (принцип надежности)
5.3. Защита инвариантов
5.3.1. Постоянная валидность
5.4. Заключение
6
Триангуляция
6.1. Кратковременная и долговременная память
6.1.1. Легаси-код и память
6.2. Объем памяти
6.2.1. Переполнение
6.2.2. Метод «Адвокат дьявола»
6.2.3. Существующее резервирование
6.2.4. Метод «Адвокат дьявола» и цикл «красный, зеленый, рефакторинг»
6.2.5. Когда тестов будет достаточно?
6.3. Заключение
7
Декомпозиция
7.1. Деградация кода
7.1.1. Пороговые значения
7.1.2. Цикломатическая сложность
7.1.3. Правило 80/24
7.2. Код, который умещается в вашей голове
7.2.1. Шестиугольные цветки
7.2.2. Связность
7.2.3. «Завистливые функции»
7.2.4. Потери при передаче
7.2.5. Анализ вместо валидации
7.2.6. Фрактальная архитектура
7.2.7. Подсчет переменных
7.3. Заключение
8
Проектирование API
8.1. Принципы проектирования API
8.1.1. Аффорданс (возможность)
8.1.2. Poka-Yoke или «защита от ошибок»
8.1.3. Пишите для читателей
8.1.4. Предпочитайте комментариям хорошо написанный код
8.1.5. Исключение имен
8.1.6. Command Query Separation (CQS), или разделение команд и запросов
8.1.7. Иерархия коммуникации
8.2. Проектирование API: примеры
8.2.1. Класс MaitreD’ (метрдотель)
8.2.2. Взаимодействие с инкапсулированным объектом
8.2.3. Детали реализации
8.3. Заключение
9
Командная работа
9.1. Git
9.1.1. Сообщение коммита
9.1.2. Непрерывная интеграция
9.1.3. Малые коммиты
9.2. Коллективное владение кодом
9.2.1. Парное программирование
9.2.2. Моб-программирование
9.2.3. Задержка код-ревью
9.2.4. Отклонение набора изменений
9.2.5. Код-ревью
9.2.6. Пулл-реквесты
9.3. Заключение
II
Устойчивость
10
Расширение кодовой базы
10.1.
Функциональные флаги
10.1.1. Календарь
10.2.
Паттерн Strangler («Душитель»)
10.2.1. Паттерн Strangler. Уровень метода
10.2.2. Паттерн Strangler. Уровень класса
10.3.
Версионирование
10.3.1. Заблаговременное предупреждение
10.4.
Заключение
11
Редактирование модульных тестов
Рефакторинг модульных тестов
11.1.1. Смена подушки безопасности
11.1.2. Добавление нового тестового кода
11.1.3. Разделяйте рефакторинг тестового и продакшен-кода
11.2.
11.3.
Заключение
12
Устранение неполадок (траблшутинг)
Понимание
12.1.1. Научный подход
12.1.2. Упрощение
12.1.3. Метод утенка
12.2.
Дефекты
12.2.1. Воспроизведение дефектов в виде тестов
12.2.2. Медленные тесты
12.2.3. Недетерминированные дефекты
12.3.
Метод бисекции
12.3.1. Метод бисекции с Git
12.4.
Заключение
13
Разделение ответственности
13.1.
Композиция
13.1.1. Вложенная композиция
13.1.2. Последовательная композиция
13.1.3. Ссылочная прозрачность
13.2.
Сквозная функциональность
13.2.1. Логирование
13.2.2. Паттерн проектирования Decorator («Декоратор»)
13.2.3. Что регистрировать
13.3.
Заключение
14
Организация рабочего процесса
14.1.
Индивидуальный процесс работы
14.1.1. Тайм-боксинг
14.1.2. Делайте перерывы
14.1.3. Используйте время разумно
14.1.4. Метод слепой печати
14.2.
Рабочий процесс в команде
14.2.1. Регулярное обновление зависимостей
14.2.2. Планирование других действий
14.2.3. Закон Конвея
Заключение
15
Очевидные аспекты
15.1.
Производительность
15.1.1. Устаревшие знания
15.1.2. Удобочитаемость
15.2.
Безопасность
15.2.1. Модель угроз STRIDE
15.2.2. Спуфинг
15.2.3. Незаконное изменение
15.2.4. Отказ от авторства
15.2.5. Раскрытие информации
15.2.6. Отказ в обслуживании
15.2.7. Повышение привилегий
15.3.
Прочие техники
15.3.1. Тестирование на основе свойств
15.3.2. Поведенческий анализ кода
15.4.
Заключение
16
Краткий обзор
Навигация
16.1.1. Общее представление
16.1.2. Организация файлов
16.1.3. Поиск деталей
16.2.
Архитектура
16.2.1. Монолитная архитектура
16.2.2. Циклы
16.3.
Использование
16.3.1. Обучение на тестах
16.3.2. Прислушивайтесь к своим тестам
16.4.
Заключение
Перечень методов
A.1. Правило 50/72
А.2. Правило 80/24
A.3. Шаблон Arrange-Act-Assert (AAA)
А.4. Бисекция
A.5. Чек-лист для новой кодовой базы
A.6. Разделение команд и запросов (CQS)
A.7. Подсчет переменных
Метод «Адвокат дьявола»
Функциональное ядро, императивная оболочка
Анализировать, а не проверять
Цикл «красный, зеленый, рефакторинг»
Код-ревью
Срез
Модель угроз STRIDE
Исключение имен
Библиография