Предисловие
Предисловие
В последнем издании книги Test-Driven Development with Python (O’Reilly), в конце, Гарри поймал себя на мысли, что задает уйму вопросов по архитектуре. Типа, как лучше всего структурировать приложение, чтобы его было легко тестировать? Это вообще, про что? Может это про покрытие модульными тестами вашей основной бизнес-логики и что бы количество необходимых вам интеграционных и сквозных тестов было минимизировано? Он дал расплывчатые ссылки на «Гексагональную архитектуру», «Порты и адаптеры» и "Functional Core, Imperative Shell", но если бы он был честен, ему пришлось бы признать, что это не то, что он действительно до конца понял, принял или применял на практике.
И тут случилось чудо! Ему посчастливилось столкнуться с Бобом, у которого есть ответы на все эти вопросы.
Боб стал архитектором программного обеспечения, потому что никто из его команды этим не занимался. Оказалось, что он неплохо справлялся с этим, но ему посчастливилось столкнуться с Яном Купером, который научил его новым способам написания кода и мышления в этой области.
Управление Сложностью, Решение Бизнес-Задач
Мы оба работаем в MADE.com, европейской компании электронной коммерции, которая продает мебель онлайн; там мы применяем методы, описанные в этой книге, для создания распределенных систем, моделирующих реальные бизнес-проблемы. Наш пример домена — первая система, созданная Бобом для MADE, и эта книга-попытка записать всё то, чему мы должны научить новых программистов, когда они присоединяются к одной из наших команд.
MADE.com управляет глобальной цепочкой поставок грузов от торговых партнеров и производителей. В целях сохранения затрат на низком уровне, мы стараемся оптимизировать доставку запасов на наши склады, чтобы у нас не было непроданных товаров, застрявших на складах.
В идеале диван, который вы хотите купить, прибудет в порт в тот самый день, когда вы решите его купить, и мы отправим его прямо к вам домой, даже не храня. Получение правильного времени — это сложный балансирующий акт, когда товары прибывают на контейнеровозе в течение трех месяцев. По пути вещи ломаются или повреждаются водой, штормы вызывают неожиданные задержки, логистические партнеры неправильно обращаются с товарами, документы пропадают, клиенты меняют свое мнение и изменяют свои заказы и так далее.
Мы решаем эти проблемы, создавая интеллектуальное программное обеспечение, представляющее виды операций, происходящие в реальном мире, чтобы мы могли автоматизировать как можно большую часть бизнеса.
Почему Python?
Если вы читаете эту книгу, то вероятно, не нужно убеждать вас в том, что Python великолепен, поэтому реальный вопрос заключается в следующем: "Зачем сообществу Python нужна такая книга?" Ответ заключается в популярности и зрелости Python: хотя Python, вероятно, является самым быстрорастущим языком программирования в мире и приближается к вершине абсолютной таблицы популярности, он только начинает решать те проблемы, над которыми мир C# и Java работал в течение многих лет. Стартапы становятся реальным бизнесом; веб-приложения и скриптовые автоматизации становятся (говорю шепотом) enterprise software.
В мире Python мы часто цитируем Дзен Python: "Должен существовать один и, желательно, только один очевидный способ сделать это."[1] К сожалению, по мере роста размера проекта наиболее очевидный способ решения задач не всегда помогает вам управлять сложностью и меняющимися требованиями.
Ни один из методов и шаблонов, которые мы обсуждаем в этой книге, не является новым, но по большей части они являются новыми для мира Python. И эта книга не является заменой классики в этой области, такой как Domain-Driven Design Эрика Эванса или Patterns of Enterprise Application Architecture Мартина Фаулера (оба опубликованы Addison-Wesley Professional), на которые мы часто ссылаемся и призываем вас пойти и прочитать.
Но все классические примеры кода в литературе, как правило, написаны на Java или C++/#, и если вы человек из рядов Python и не использовали ни один из этих языков в течение длительного времени (или вообще никогда), то эти листинги кода могут быть довольно…трудными. Видимо это и есть причина, по которой последнее издание другого классического текста, Fowler’s Refactoring (Addison-Wesley Professional), написано в JavaScript.
TDD, DDD, и Event-Driven Architecture
В порядке популярности назовём три инструмента для управления сложностью:
Test-driven development (TDD) Разработка на основе тестов. Помогает нам создавать правильный код и проводить рефакторинг или добавлять новые функции, не опасаясь регресса. Но бывает сложно извлечь максимальную пользу из наших тестов: как сделать так, чтобы они выполнялись как можно быстрее? Чтобы мы получили как можно более качественное покрытие и обратную связь от быстрых модульных тестов без зависимостей (dependency-free unit tests) и имели минимальное количество более медленных, нестабильных сквозных (end-to-end) тестов?
Domain-driven design (DDD) Разработка на основе поведения. Просит нас сосредоточить наши усилия на построении хорошей модели бизнес-сферы, но как мы можем убедиться, чтобы наши модели не были обременены инфраструктурными проблемами и их не было трудно изменить?
Loose coupling Слабосвязанные (микросервисы), интегрированные через сообщения (иногда называемые reactive microservices), являются хорошо зарекомендовавшим себя решением проблемы управления сложностью в нескольких приложениях или бизнес-доменах. Но не всегда очевидно, как сделать так, чтобы они соответствовали широко распространённым инструментам мира Python-Flask, Django, Celery и так далее.
| Не пугайтесь, если вы не работаете с микросервисами (или не заинтересованы в них). Подавляющее большинство моделей, которые мы обсудим, включая большую часть материалов событийной архитектуры, абсолютно применимы в монолитной архитектуре. |
Наша цель в этой книге-представить несколько классических архитектурных моделей и показать, как они поддерживают TDD, DDD и event-driven сервисы. Мы надеемся, что он послужит ориентиром для их реализации в питоническом ключе, и что люди смогут использовать его в качестве первого шага к дальнейшим исследованиям в этой области.
Кому следует прочитать эту книгу
Вот несколько мыслей, которые мы предполагаем справедливо сказать о тебе, дорогой читатель:
Ты был близок к некоторым достаточно сложным приложениям Python.
Ты видел, а может сам испытал ту боль, которая приходит вместе с попыткой справиться с этой сложностью.
Ты не обязательно знаешь что-либо о DDD или любом из классических шаблонов архитектуры приложений.
Мы структурируем наши исследования архитектурных паттернов вокруг примера приложения, выстраивая его главу за главой. Мы используем TDD в работе, поэтому обычно сначала показываем списки тестов, а затем их реализацию. Если вы не привыкли работать с тестом, сначала это может показаться немного странным, но мы надеемся, что вы скоро привыкнете видеть код "используемым" (то есть снаружи), прежде чем увидите, как он построен внутри.
Мы используем некоторые специфические фреймворки и технологии Python, включая Flask, SQLAlchemy и pytest, а также Docker и Redis. Если вы уже знакомы с ними, то это не повредит, но вряд ли это необходимо. Одной из наших главных целей в этой книге является построение архитектуры, для которой конкретные технологические решения становятся второстепенными деталями реализации.
Краткий обзор того, что будет дальше
Книга разделена на две части; Вот некоторые темы, которые мы рассмотрим, и главы, в которых они живут.
#Часть1
- Domain modeling и DDD (Chapters 1, 2 и 7)
На каком-то уровне каждый усвоил урок, что сложные бизнес-задачи должны быть отражены в коде, в виде модели предметной области. Но почему всегда кажется, что это так трудно сделать, не запутавшись в инфраструктурных проблемах, наших веб-фреймворках или чем-то еще? В первой главе мы даем широкий обзор domain modeling и DDD, а также показываем, как начать работу с моделью, которая не имеет внешних зависимостей и быстрых модульных тестов. Позже мы вернемся к шаблонам DDD, чтобы обсудить, как выбрать правильный агрегат и как этот выбор связан с вопросами целостности данных.
- Repository, Service Layer, и Unit of Work patterns (Chapters 2, 4, и 5)
В этих трех главах мы представляем три тесно связанных и взаимно усиливающих друг друга паттерна, которые поддерживают наше стремление сохранить модель свободной от посторонних зависимостей. Мы выстроим слой абстракции вокруг постоянного хранилища, и уровень сервиса, чтобы определить точки входа в нашу систему и захватить основные варианты использования. Мы покажем, как этот слой позволяет легко создавать тонкие точки входа в нашу систему, будь то API Flask или CLI (Command Line Interface - Интерфейс командной строки).
- Некоторые соображения о тестировании и абстракциях (Chapter 3 и 5)
После представления первой абстракции (паттерна Repository) воспользуемся возможностью для общего обсуждения того, как выбирать абстракции и какова их роль в выборе того, как наше программное обеспечение связано друг с другом. После знакомства с шаблоном Service Layer, немного поговорим о построении test pyramid и написании модульных тестов на максимально возможном уровне абстракции.
#Часть2
- Архитектура, управляемая событиями (Chapters 8-11)
Мы вводим еще три взаимно усиливающих шаблона: Domain Events, Message Bus, и Handler patterns. События домена (Domain Events)-это средство передачи идеи о том, что некоторые взаимодействия с системой являются триггерами для других. Мы используем шину сообщений Message Bus, чтобы позволить действиям вызывать события и вызывать соответствующие handlers (обработчики). Мы переходим к обсуждению того, как события могут быть использованы в качестве шаблона для интеграции между службами в архитектуре микросервисов. Наконец, мы различаем команды и события. Наше приложение теперь по сути является системой обработки сообщений.
- Разделение ответственности по командам и запросам ([chapter_12_cqrs])
Мы приводим пример разделения ответственности команд-запросов с событиями и без событий.
- Инъекция зависимостей ([chapter_13_dependency_injection])
Мы приводим в порядок наши явные и неявные зависимости и реализуем простую структуру внедрения зависимостей.
Дополнительный контент
Как мне попасть туда отсюда?[2] ([epilogue_1_how_to_get_there_from_here]):: Реализация архитектурных шаблонов всегда выглядит легко, когда вы показываете простой пример, начиная с нуля, но многие из вас, вероятно, зададутся вопросом, как применить эти принципы к существующему программному обеспечению. Мы дадим несколько указаний в эпилоге и некоторые ссылки для дальнейшего чтения.
Примеры кода и совместное кодирование
Постепенно читая эту книгу вы, вероятно, согласитесь с нами, когда мы скажем, что лучший способ узнать о коде — это код. Большую часть того, что мы знаем, мы узнали из общения с людьми, совместного написания кода с ними и обучения на практике, и мы хотели бы воссоздать этот опыт для вас как можно точнее в этой книге.
В результате мы построили книгу на примере одного проекта (хотя иногда мы приводим и другие примеры). Мы будем развивать этот проект по мере продвижения глав, как если бы вы были в паре с нами, и мы объясняем, что мы делаем и почему на каждом этапе.
Но чтобы по-настоящему разобраться с этими шаблонами, вам нужно повозиться с кодом и почувствовать, как он работает. Вы найдете весь код на GitHub; у каждой главы есть своя ветка. Вы также можете найти список веток на GitHub.
Вот три способа кодирования вместе с книгой:
Начните свой собственное репозиторий и попробуйте создать приложение, как это делаем мы, следуя примерам из листингов в книге и время от времени заглядывая в наше репо за подсказками. Однако предупреждаю: если вы читали предыдущую книгу Гарри и кодировали вместе с ней, вы обнаружите, что эта книга требует от вас проявить больше самостоятельности; вам, возможно, придется сильно полагаться на рабочие версии на GitHub.
Попробуйте применить каждый шаблон, главу за главой, к вашему собственному (желательно маленькому/игрушечному) проекту и посмотрите, сможете ли вы заставить его работать для вашего варианта использования. Высокий риск/высокая награда (и, кроме того, достаточные усилия!). Возможно придётся изрядно попотеть, чтобы заставить какие то вещи работать в соответствии со спецификой вашего проекта, но, с другой стороны, вероятно вы, узнаете много полезного.
В каждой главе мы описываем "Упражнение для читателя" и даём ссылки на GitHub, где вы можете скачать частично готовый код для главы с несколькими недостающими частями, чтобы написать его самостоятельно.
Особенно если вы намереваетесь применить некоторые из этих паттернов в своих собственных проектах, работа с простым примером-отличный способ безопасно практиковаться.
| По крайней мере, выполняйте «git checkout» кода из нашего репозитория при чтении каждой главы. Возможность сразу же увидеть код в контексте реального работающего приложения поможет ответить на множество вопросов по ходу дела и сделает все более реальным. Вы найдете инструкции, как это сделать, в начале каждой главы. |
Лицензия
Код (и онлайн-версия книги) находится под лицензией Creative Commons CC BY-NC-ND, что означает, что вы можете свободно копировать и делиться им с кем угодно в некоммерческих целях при условии указания авторства. Если вы хотите повторно использовать какой-либо контент из этой книги и у вас есть какие-либо опасения по поводу лицензии, свяжитесь с O’Reilly permissions@oreilly.com.
Печатное издание лицензируется по-другому; см. страницу об авторских правах.
Условные обозначения, используемые в этой книге
В этой книге используются следующие типографские условные обозначения:
- Курсив
Указывает новые термины, URL-адреса, адреса электронной почты, имена файлов и расширения файлов.
Постоянная ширинаИспользуется для листинга программ, а также в абзацах для обозначения программных элементов, таких как имена переменных или функций, базы данных, типы данных, переменные среды, операторы и ключевые слова.
Постоянная ширина жирный шрифтПоказывает команды или другой текст, который должен быть набран буквально пользователем.
Курсив постоянной шириныПоказывает текст, который должен быть заменен пользовательскими значениями или значениями, определяемыми контекстом.
Этот элемент означает подсказку или предложение. |
Этот элемент обозначает общее примечание. |
Этот элемент указывает на предупреждение или предостережение. |
Онлайн-обучение O’Reilly
Более 40 лет O’Reilly Media предоставляет технологии и бизнес-тренинги, знания и идеи, чтобы помочь компаниям добиться успеха. |
Наша уникальная сеть экспертов и новаторов делится своими знаниями и опытом с помощью книг, статей, конференций и нашей онлайн-платформы обучения. Платформа онлайн-обучения O’Reilly предоставляет вам доступ по требованию к живым учебным курсам, углубленным учебным путям, интерактивным средам кодирования и обширной коллекции текстов и видео от O’Reilly и более чем 200 других издателей. Для получения дополнительной информации, пожалуйста, посетите сайт http://oreilly.com.
Как связаться с O’Reilly
Пожалуйста, направляйте комментарии и вопросы, касающиеся этой книги, издателю:
- O’Reilly Media, Inc.
- 1005 Gravenstein Highway North
- Sebastopol, CA 95472
- 800-998-9938 (in the United States or Canada)
- 707-829-0515 (international or local)
- 707-829-0104 (fax)
У нас есть веб-страница для этой книги, где мы перечисляем ошибки, примеры и любую дополнительную информацию. Вы можете получить доступ к этой странице по адресу https://oreil.ly/architecture-patterns-python.
Email bookquestions@oreilly.com для комментариев и технических вопросов по этой книге.
Для получения дополнительной информации о наших книгах, курсах, конференциях и новостях посетите наш веб-сайт по адресу http://www.oreilly.com.
Найдите нас на Facebook: http://facebook.com/oreilly
Следите за нами в Twitter: http://twitter.com/oreillymedia
Смотрите нас на YouTube: http://www.youtube.com/oreillymedia
Благодарности
Нашим техническим обозревателям Дэвиду Седдону, Эду Юнгу и Хайнеку Шлаваку: мы абсолютно не заслуживаем вас. Вы все невероятно преданные, добросовестные и строгие. Каждый из вас безмерно умен, и ваши разные точки зрения были полезны и дополняли друг друга. Спасибо вам от всего сердца.
Огромное спасибо всем нашим читателям за их комментарии и предложения: Йен Купер, Абдулла Арифф, Джонатан Мейер, Гил Гонсалвес, Матье Чоплин, Бен Джадсон, Джеймс Грегори, Лукаш Лехович, Клинтон Рой, Виторино Араужо, Сьюзан Гудбоди, Джош Харвуд, Дэниел Батлер, Лю Хайбин, Джимми Вергиа Игнасиа Игнас Канестрани, Ренне Роча, Педроаби, Ашиа Завадук, Йостейн Лейра, Брэндон Роудс, Язепс Баско, Симкимсия, Адриен Брюнет и многие другие; приносим свои извинения, если мы пропустили Вас в этом списке.
Супер-мега-спасибо нашему редактору Корбину Коллинзу за его нежное щебетание и за то, что он неутомимый защитник читателя. В такой же степени выражаем благодарность производственному персоналу Кэтрин Тозер, Шэрон Уилки, Эллен Траутман-Заиг и Ребекке Демарест за вашу преданность делу, профессионализм и внимание к деталям. Эта книга неизмеримо улучшена благодаря вам.
Любые ошибки, оставшиеся в книге, естественно, являются нашими собственными.
python -c "import this"
Комментарии
Отправить комментарий