Padrões de arquitetura vistos com Python
(cosmicpython.com)- Aplicações Python complexas, à medida que crescem, passam a ser difíceis de testar e alterar usando apenas formas simples de implementação; este livro trata a solução por meio de padrões de arquitetura com exemplos de código
- Usando como exemplo as vendas online de móveis da MADE.com e sua cadeia de suprimentos global, o foco está na modelagem de domínio que traduz problemas operacionais do mundo real para modelos de software
- Os eixos centrais são TDD, DDD e arquitetura orientada a eventos, com o objetivo de ter testes unitários rápidos, poucos testes E2E, modelos separados da infraestrutura e integração baseada em mensagens
- Usa Flask, SQLAlchemy, pytest, Docker e Redis, mas o foco é construir uma estrutura em que a escolha de tecnologias específicas fique relegada a detalhes de implementação
- Pode ser lido por quem já lidou com aplicações Python complexas, sem necessidade de conhecer previamente DDD ou padrões clássicos de arquitetura de aplicações
A motivação começou com uma estrutura fácil de testar
- Depois do livro anterior de Harry, Test-Driven Development with Python, ficou a pergunta sobre como estruturar aplicações para que sejam fáceis de testar
- O ponto central é criar uma estrutura em que a lógica de negócio possa ser coberta principalmente por testes unitários, minimizando a quantidade de testes de integração e E2E
- Conceitos como "Hexagonal Architecture", "Ports and Adapters" e "Functional Core, Imperative Shell" já eram mencionados, mas na época ainda não havia compreensão nem prática suficientes deles
- Bob tornou-se arquiteto porque não havia ninguém na equipe responsável por arquitetura de software, e aprendeu com Ian Cooper uma nova forma de escrever código e pensar sobre ele
O caso da MADE.com: modelando a cadeia de suprimentos em software
- Os dois autores trabalharam na empresa europeia de e-commerce MADE.com e aplicaram as técnicas do livro na construção de sistemas distribuídos que modelam problemas reais de negócio
- O domínio de exemplo se baseia no primeiro sistema criado por Bob na MADE, com o objetivo de organizar o que precisava ser ensinado a novos programadores que entravam na equipe
- A MADE.com opera uma cadeia de suprimentos global formada por parceiros de carga e fabricantes
- Para reduzir custos, busca otimizar entregas para evitar que o estoque fique parado por muito tempo em armazéns
- No cenário ideal, o sofá chegaria ao porto no mesmo dia em que o cliente o comprasse, sendo entregue à casa do cliente sem armazenamento intermediário
- Como os produtos podem levar 3 meses para chegar em navios de contêineres, acertar o timing é difícil
- Na operação real, surgem constantemente variáveis como danos, alagamentos, atrasos causados por tempestades, erros de processamento de parceiros logísticos, documentos faltando e mudanças de pedido por parte dos clientes
- Para lidar com esses problemas, a ideia é representar a operação do mundo real em software e automatizar o máximo possível do trabalho
Os limites que aparecem quando um projeto Python cresce
- Python cresceu e amadureceu rapidamente, mas agora começa a assumir de forma mais séria o tipo de problema com que os ecossistemas de C# e Java lidam há muito tempo
- Startups viram negócios reais, e web apps e automações por script crescem até se tornarem software corporativo
- A filosofia de Python inclui “There should be one—and preferably only one—obvious way to do it”, mas, quando o projeto cresce, a forma mais óbvia nem sempre é a melhor para gerenciar complexidade e mudanças de requisitos
- As técnicas e padrões abordados no livro não são novos, mas ainda são relativamente novos para grande parte do mundo Python
- O livro não pretende substituir Domain-Driven Design, de Eric Evans, nem Patterns of Enterprise Application Architecture, de Martin Fowler; ele faz referência frequente a esses clássicos e recomenda sua leitura
- Como muitos exemplos de código da literatura existente foram escritos em Java ou C++/#, a leitura pode ser mais pesada para desenvolvedores Python
Três ferramentas para gerenciar complexidade
- Desenvolvimento orientado a testes (TDD) ajuda a criar o código correto e a refatorar ou adicionar funcionalidades sem medo de regressões
- O livro trata de como executar testes o mais rápido possível
- Como obter o máximo de cobertura e feedback com testes unitários rápidos e sem dependências
- E como minimizar testes E2E lentos e instáveis
- Domain-Driven Design (DDD) leva o foco para a construção de bons modelos do domínio de negócio
- O livro mostra como impedir que o modelo fique preso a preocupações de infraestrutura
- E como evitar que ele se torne difícil de mudar
- Microsserviços fracamente acoplados e integrados por mensagens, às vezes chamados de reactive microservices, são apresentados como uma forma de lidar com a complexidade entre várias aplicações ou domínios de negócio
- Nem sempre é claro como encaixar isso nas ferramentas já existentes do ecossistema Python, como Flask, Django e Celery
- Mesmo que você não use ou não tenha interesse em microsserviços, a maior parte dos padrões do livro e boa parte do conteúdo sobre arquitetura orientada a eventos também se aplica a arquiteturas monolíticas
Leitor-alvo e conhecimentos prévios
- O livro assume leitores que já tiveram contato próximo com aplicações Python de certa complexidade
- É voltado para quem já sentiu na prática a dor de gerenciar complexidade
- Não é necessário conhecimento prévio de DDD nem de padrões clássicos de arquitetura de aplicações
- A explicação é construída capítulo a capítulo em torno de uma aplicação de exemplo
- Como os autores usam TDD no trabalho, frequentemente mostram primeiro o código de teste e depois a implementação
- Flask, SQLAlchemy, pytest, Docker e Redis aparecem no livro, mas conhecê-los antes ajuda sem ser obrigatório
- Um dos principais objetivos é criar uma arquitetura em que escolhas tecnológicas específicas sejam apenas pequenos detalhes de implementação
Estrutura do livro
- O livro é dividido em duas partes
-
Parte 1: Arquitetura que dá suporte à modelagem de domínio
- Modelagem de domínio e DDD são tratados nos capítulos 1, 2 e 7
- Parte-se da premissa de que problemas complexos de negócio devem ser refletidos em um modelo de domínio dentro do código
- Explica como começar com um modelo sem dependências externas e com testes unitários rápidos
- Depois volta ao tema da escolha adequada de aggregate e aos problemas de integridade dos dados
- Os padrões Repository, Service Layer e Unit of Work são abordados nos capítulos 2, 4 e 5
- Esses padrões se complementam para separar o modelo de dependências desnecessárias
- Cria-se uma camada de abstração em torno do armazenamento persistente e uma camada de serviço para capturar os pontos de entrada do sistema e os principais casos de uso
- O livro mostra uma estrutura que facilita criar pontos de entrada enxutos, como uma API Flask ou uma CLI
- A discussão sobre abstração e testes continua nos capítulos 3 e 5
- Depois de apresentar o padrão Repository, o livro trata de como escolher abstrações e do papel delas nas formas de acoplamento
- Após o padrão Service Layer, entra em cena a pirâmide de testes e como escrever testes unitários no nível mais alto de abstração possível
-
Parte 2: Arquitetura orientada a eventos
- A arquitetura orientada a eventos é tratada dos capítulos 8 a 11
- São apresentados os padrões Domain Events, Message Bus e Handler
- Domain Events são um meio de representar a ideia de que certas interações no sistema disparam outras ações
- O Message Bus faz com que ações disparem eventos e chamem o handler adequado
- O livro mostra como usar eventos como padrão de integração entre serviços em arquiteturas de microsserviços
- Faz a distinção entre commands e events, e a aplicação passa a ser, em essência, um sistema de processamento de mensagens
- No capítulo 12, um exemplo de CQRS é apresentado tanto com uso de eventos quanto sem eles
- No capítulo 13, são organizadas dependências explícitas e implícitas, e é implementado um framework simples de injeção de dependência
- No epílogo, os autores mostram como aplicar esses princípios a software já existente, em vez de apenas a um exemplo simples começando do zero, além de sugerirem leituras adicionais
Código de exemplo e como acompanhar
- O livro é estruturado em torno de um único projeto de exemplo, que vai sendo expandido gradualmente ao longo dos capítulos
- Os autores consideram importante que o leitor mexa no código de verdade para desenvolver intuição sobre como os padrões funcionam
- Todo o código está no GitHub, e cada capítulo tem sua própria branch
- A lista de branches pode ser vista na página de branches do GitHub
- São sugeridas três formas de acompanhar
- Criar seu próprio repositório e construir a aplicação seguindo os exemplos do livro, consultando o repositório dos autores quando necessário
- Aplicar cada padrão, capítulo a capítulo, em um pequeno projeto seu
- Praticar rapidamente usando o "Exercise for the Reader" de cada capítulo e o código no GitHub com algumas partes em branco
- Para quem pretende aplicar os padrões no próprio projeto, trabalhar primeiro com um exemplo simples é uma prática segura
- Recomenda-se, no mínimo, usar
git checkoutao ler cada capítulo para obter o código do repositório e analisá-lo no contexto de uma aplicação real em funcionamento
Licença e formato
- O código e a versão online usam a licença Creative Commons CC BY-NC-ND
- Para fins não comerciais
- Com atribuição de autoria
- Permitindo cópia e compartilhamento
- A edição impressa segue uma licença separada, e o livro orienta que dúvidas sobre reutilização sejam encaminhadas à O’Reilly
- As convenções tipográficas do livro distinguem itálico, monoespaçado, monoespaçado em negrito e monoespaçado em itálico
- Itálico indica termos novos, URLs, endereços de email, nomes de arquivo e extensões
- Monoespaçado indica listagens de programas e elementos de código
- Monoespaçado em negrito indica comandos ou textos que o usuário deve digitar exatamente como estão
- Monoespaçado em itálico indica texto que deve ser substituído por valores fornecidos pelo usuário ou definidos pelo contexto
1 comentários
Há uma edição em coreano disponível: Padrões de Arquitetura em Python