Популярность Python продолжает расти, а значит, проекты, созданные на этом языке программирования, становятся все масштабнее и сложнее. Многие разработчики проявляют интерес к высокоуровневым паттернам проектирования, таким как чистая и событийно-управляемая архитектура и паттерны предметно-ориентированного проектирования (DDD). Но их адаптация под Python не всегда очевидна. Гарри Персиваль и Боб Грегори познакомят вас с проверенными паттернами, чтобы каждый питонист мог управлять сложностью приложений и получать максимальную отдачу от тестов. Теория подкреплена примерами на чистом Python, лишенном синтаксической избыточности Java и C#.
В этой книге:
• «Инверсия зависимостей» и ее связи с портами и адаптерами (гексагональная/чистая архитектура).
• Различия между паттернами «Сущность», «Объект-значение» и «Агрегат» в рамках DDD.
• Паттерны «Репозиторий» и «UoW», обеспечивающие постоянство хранения данных.
• Паттерны «Событие», «Команда» и «Шина сообщений».
• Разделение ответственности на команды и запросы (CQRS).
• Событийно-управляемая архитектура и реактивные расширения.
Author(s): Гарри Персиваль, Боб Грегори
Series: Для профессионалов
Edition: 1
Publisher: Питер
Year: 2022
Language: Russian
Commentary: Vector PDF
Pages: 336
City: СПб.
Tags: Python; Microservices; Flask; Unit Testing; Testing; Performance; Event-Driven Architecture; Dependency Injection; Pyramid; Domain-Driven Design; Domain Modeling; Architecture Patterns; Command-Query Responsibility Segregation; Test-Driven Development
Предисловие
Управлять сложностью, решая бизнес-задачи
Почему Python?
TDD, DDD и событийно-управляемая архитектура
Для кого эта книга
Краткий обзор книги
Дополнительные материалы
Примеры кода и работа с ним
Условные обозначения
Благодарности
От издательства
Введение
Почему в проекте что-то идет не так?
Инкапсуляции и абстракции
Разделение на слои
Принцип инверсии зависимостей
Место для всей бизнес-логики: модель предметной области
Часть I. Создание архитектуры для поддержки моделирования предметной области
Глава 1. Моделирование предметной области
Что такое модель предметной области?
Изучение языка предметной области
Юнит-тестирование моделей предметных областей
Не все должно быть объектом: функция службы предметной области
Глава 2. Паттерн «Репозиторий»
Организация постоянного хранения модели предметной области
Немного псевдокода: что нам потребуется?
Применение принципа инверсии зависимостей для доступа к данным
Напоминание: наша модель
Введение паттерна «Репозиторий»
Теперь поддельный репозиторий для тестов создается просто!
Что такое порт и что такое адаптер в Python?
Выводы
Глава 3. О связанности и абстракциях
Абстрагирование состояния способствует тестопригодности
Выбор правильной абстракции (-й)
Реализация выбранных абстракций
Выводы
Глава 4. Первый вариант использования: API фреймворка Flask и сервисный слой
Соединение приложения с реальным миром
Первый сквозной тест
Простая реализация
Состояния ошибок, требующие проверки базы данных
Введение сервисного слоя и использование поддельного репозитория для юнит-теста
Почему все называется службой?
Складываем все в папки, чтобы понять, где оно находится
Выводы
Глава 5. TDD на верхней и нижней передачах
Как выглядит пирамида тестирования?
Должны ли тесты слоя предметной области перейти в сервисный слой?
Какие тесты писать
Верхняя и нижняя передачи
Устранение связей в тестах сервисного слоя от предметной области
Улучшение посредством сквозных тестов
Выводы
Глава 6. Паттерн «Единица работы»
Паттерн «Единица работы» сотрудничает с репозиторием
Тестирование Единицы работы с интеграционными тестами
Единица работы и ее контекстный менеджер
Использование паттерна «Единица работы» в сервисном слое
Явные тесты для форм поведения по фиксации/откату
Явные и неявные фиксации
Примеры: использование паттерна «Единица работы» для группировки многочисленных операций в атомарную единицу
Приведение в порядок интеграционных тестов
Выводы
Глава 7. Агрегаты и границы согласованности
Почему бы просто не записать все в электронную таблицу?
Инварианты, ограничения и согласованность
Что такое агрегат?
Выбор агрегата
Один агрегат = один репозиторий
А что на счет производительности?
Оптимистичная конкурентность с номерами версий
Тестирование правил целостности данных
Выводы
Итоги части I
Часть II. Событийно-управляемая архитектура
Глава 8. События и шина сообщений
Как избежать беспорядка
Принцип единственной обязанности
Катимся на шине сообщений!
Вариант 1: сервисный слой берет события из модели и помещает их в шину сообщений
Вариант 2: сервисный слой инициирует собственные события
Вариант 3: Единица работы публикует события в шине сообщений
Выводы
Глава 9. Катимся в город на шине сообщений
Новое требование приводит к новой архитектуре
Рефакторинг функций служб для обработчиков сообщений
Реализация нового требования
Тест-драйв нового обработчика
Необязательно: юнит-тест обработчиков событий в изоляции с помощью поддельной шины сообщений
Выводы
Глава 10. Команды и обработчик команд
Команды и события
Различия в обработке исключений
События, команды и обработка ошибок
Синхронное восстановление после ошибок
Выводы
Глава 11. Событийно-управляемая архитектура: использование событий для интеграции микросервисов
Распределенный комок грязи, или мыслить существительными
Обработка ошибок в распределенных системах
Альтернатива: временное устранение связанности при помощи асинхронного обмена сообщениями
Использование канала «издатель/подписчик» хранилища Redis для интеграции
Тестирование с помощью сквозного теста
Внутренние события против внешних
Выводы
Глава 12. Разделение ответственности команд и запросов
Модели предметной области для записи
Большинство пользователей не собираются покупать вашу мебель
PRG и разделение команд и запросов
Хватайте свой обед, ребята
Тестирование представлений CQRS
«Очевидная» альтернатива 1: использование существующего репозитория
Модель предметной области не оптимизирована для операций чтения
«Очевидная» альтернатива № 2: использование ORM
SELECT N+1 и другие соображения по поводу производительности
Время прыгать через акулу
Изменить реализацию модели чтения очень просто
Выводы
Глава 13. Внедрение зависимостей (и начальная загрузка)
Неявные зависимости против явных
Разве явные зависимости не кажутся странными и Java-подобными?
Подготовка обработчиков: внедрение зависимостей вручную с помощью замыканий и частичных применений
Альтернатива с использованием классов
Сценарий начальной загрузки
Шина сообщений получает обработчики во время выполнения
Использование начальной загрузки в точках входа
Внедрение зависимостей в тестах
«Правильное» создание адаптера: рабочий пример
Выводы
Эпилог
И что теперь?
Как мне добраться туда?
Разделение запутанных обязанностей
Определение агрегатов и ограниченных контекстов
Управляемый событиями подход для перехода к микросервисам через паттерн «Душитель»
Как убедить стейкхолдеров попробовать что-то новое
Вопросы наших научных редакторов, которые мы не включили в основной текст
Выстрел в ногу
Книги для обязательного прочтения
Выводы
Приложение А. Сводная диаграмма и таблица
Приложение Б. Шаблонная структура проекта
Приложение В. Замена инфраструктуры: делам все с помощью CSV
Приложение Г. Паттерны «Репозиторий» и «Единица работы» с Django
Приложение Д. Валидация
Об авторах
Об обложке