Analisar um aplicativo e identificar os limites de decomposição
Para mover o aplicativo para uma arquitetura de microsserviços, a Fabrikam precisa avaliar aplicativo atual e determinar o escopo e o limite de cada microsserviço. Para essa avaliação, eles usarão a estrutura dedesign orientado pelo domínio (DDD). Vamos ver como a empresa aplica isso ao aplicativo.
Observação
Este artigo não é destinado a mostrar uma análise de domínio completa e abrangente. Mantivemos o exemplo breve propositalmente para ilustrar os pontos principais. Para obter mais informações sobre o DDD, confira a seção "Saber mais" no resumo no fim deste módulo.
O que é o design orientado por domínio?
O DDD é uma abordagem ao design de sistemas originalmente apresentada por Erik Evans em seu livro de 2005, Domain-Driven Design: Tackling Complexity in the Heart of Software. Essa abordagem inclui três elementos principais:
- focar no domínio principal e na lógica de domínio;
- estruturar o design em um modelo do domínio;
- conduzir uma colaboração iterativa entre as equipes técnicas e os parceiros de negócios para aprimorar o sistema constantemente.
O DDD fornece uma estrutura que pode ajudar você pela maior parte do processo de obtenção de um conjunto de microsserviços bem projetado. Ele tem duas fases diferentes, a estratégica e a tática. No DDD estratégico, você define a estrutura em grande escala do sistema. O DDD estratégico ajuda a garantir que sua arquitetura permaneça concentrada em capacidades comerciais. O DDD tático fornece um conjunto de padrões de design que você pode usar para criar o modelo de domínio. Esses padrões incluem entidades, agregações e serviços de domínio. Esses padrões táticos lhe ajudam a criar microsserviços que são acoplados flexivelmente e coesos.
Durante a fase estratégica de DDD, você mapeia fora do domínio empresarial e define contextos limitados para seus modelos de domínio. DDD tático é quando você define os modelos de domínio com mais precisão. Os padrões táticos são aplicados dentro de um único contexto limitado. Em uma arquitetura de microsserviços, estamos interessados nos padrões de entidade e de agregação. Aplicar esses padrões nos ajuda a identificar limites naturais para os serviços em nosso aplicativo. Como um princípio geral, um microsserviço não deve ser menor do que uma agregação e não pode exceder um contexto limitado.
Em um alto nível, você pode dividir esse processo em quatro etapas:
- Analise o domínio empresarial para entender os requisitos funcionais do aplicativo. A saída desta etapa é uma descrição informal do domínio, que pode ser refinada em um conjunto mais formal de modelos de domínio.
- Defina os contextos limitados do domínio. Cada contexto limitado contém um modelo de domínio que representa um subdomínio específico do aplicativo maior.
- Dentro de um contexto limitado, aplique padrões DDD táticos para definir entidades, agregações e serviços de domínio.
- Use os resultados da etapa anterior para identificar os microsserviços no aplicativo.
Vamos examinar mais detalhadamente cada uma dessas etapas.
Analisar o domínio empresarial
O DDD começa modelando o domínio empresarial e criando um modelo de domínio. O modelo de domínio é um modelo abstrato do domínio empresarial. Ele destila e organiza os dados de conhecimento do domínio e fornece uma linguagem comum para desenvolvedores e especialistas de domínio.
Comece mapeando todas as funções de negócios e as respectivas conexões. Essa análise é um esforço colaborativo que envolve especialistas em domínio, arquitetos de software e outros stakeholders. Você não precisa usar nenhum formalismo específico. Esboce um diagrama ou desenhe-o em um quadro de comunicações.
Conforme você preencher o diagrama, poderá começar a identificar subdomínios discretos. Quais funções estão intimamente relacionadas? Quais funções são fundamentais para os negócios e quais fornecem serviços auxiliares? O que é o grafo de dependência? Durante a fase inicial, você não se importa com tecnologias ou detalhes de implementação. Dito isso, você deverá tomar nota do local em que o aplicativo precisa se integrar com sistemas externos como CRM, processamento do pagamento ou sistemas de cobrança.
Definir contextos limitados
O modelo de domínio inclui representações de objetos reais no mundo, tais como usuários, drones e pacotes. Mas isso não significa que todas as partes do sistema precisam usar as mesmas representações para as mesmas coisas.
Por exemplo, subsistemas que lidam com reparo de drones e análise preditiva precisam representar muitas características físicas de drones. Essas características incluem histórico de manutenção, quilometragem, idade, número do modelo e detalhes de desempenho. Porém, quando é hora de agendar uma entrega, esses elementos não importam. O subsistema de agendamento só precisa saber se um drone está disponível e a ETA (hora prevista de chegada) para coleta e entrega.
Se tentarmos criar um único modelo para esses dois subsistemas, ele será desnecessariamente complexo. Também seria mais difícil para o modelo evoluir ao longo do tempo, porque as alterações precisariam atender a várias equipes trabalhando em subsistemas separados. Geralmente é melhor criar modelos separados que representam a mesma entidade do mundo real (nesse caso, um drone) em dois contextos diferentes. Cada modelo contém apenas os recursos e os atributos que são relevantes no contexto específico dele.
Essa abordagem é onde o conceito DDD de contextos limitados entra em jogo. Um contexto limitado é simplesmente o limite em um domínio em que um modelo de domínio específico se aplica. Examinando o diagrama anterior, é possível agrupar as funcionalidades dependendo de várias funções compartilharem ou não um único modelo de domínio.
Definir entidades, agregações e serviços
DDD tático é quando você define os modelos de domínio com mais precisão. Os padrões táticos são aplicados dentro de um único contexto limitado. Em uma arquitetura de microsserviços, estamos interessados nos padrões de entidade e de agregação. Aplicar esses padrões nos ajuda a identificar limites naturais para os serviços em nosso aplicativo. Como um princípio geral, um microsserviço não deve ser menor do que uma agregação e não pode exceder um contexto limitado.
Há vários padrões de DDD tático a serem considerados:
- Entidades: uma entidade é um objeto com uma identidade exclusiva que persiste ao longo do tempo. Por exemplo, em um aplicativo de serviços bancários, clientes e contas são entidades.
- Objetos de valor: Um objeto de valor não tem identidade. Os valores de seus atributos o definem, e ele é imutável. Exemplos comuns de objetos de valor incluem valores de datas e horas, moedas e cores.
- Agregações: uma agregação define um limite de consistência em torno de uma ou mais entidades. A finalidade de uma agregação é modelar invariáveis transacionais. As coisas no mundo real têm redes de relacionamentos complexas. Os clientes criam pedidos, os pedidos contêm produtos, os produtos têm fornecedores e assim por diante. Se o aplicativo modificar vários objetos relacionados, como ele garantirá a consistência? Como manter o controle de invariáveis e impô-las?
- Domínio e serviços de aplicativo: na terminologia DDD, um serviço é um objeto que implementa uma lógica sem conter nenhum estado. Evans faz distinção entre serviços de domínio, que encapsulam a lógica do domínio, e serviços de aplicativo, que fornecem funcionalidades técnicas. Os serviços de aplicativo geralmente incluem funcionalidades técnicas, como autenticação de usuário ou envio de uma mensagem SMS. Serviços de domínio geralmente são usados para modelar comportamento que abrange várias entidades.
- Eventos de domínio: eventos de domínio podem ser usados para notificar outras partes do sistema quando algo acontece. Como o nome sugere, eventos de domínio devem significar algo dentro do domínio. Por exemplo, "um registro foi inserido em uma tabela" não é um evento de domínio. "Uma entrega foi cancelada" é um evento de domínio. Eventos de domínio são especialmente relevantes em uma arquitetura de microsserviços. Já que microsserviços são distribuídos e não compartilham armazenamentos de dados, eventos de domínio fornecem uma maneira para os microsserviços se coordenarem entre si.
A equipe de desenvolvimento da Fabrikam identificou as seguintes entidades no sistema da empresa:
- Entrega
- Pacote
- Drone
- Conta
- Confirmação
- Notificação
- Marca
As quatro primeiras entidades, entrega, pacote, drone e conta, são todas agregações que representam limites de consistência transacional. Confirmações e notificações são entidades filho de entregas. As marcas são entidades filhas de pacotes.
Os objetos de valor neste design incluem Localização, ETA, PackageWeight e PackageSize.
Há dois eventos de domínio:
- Enquanto um drone está em trânsito, a entidade drone envia eventos DroneStatus que descrevem a localização do drone e o status dele (por exemplo, em curso, descarregou).
- A entidade entrega envia eventos DeliveryTracking sempre que o estágio de uma entrega é alterado. Esses eventos incluem DeliveryCreated, DeliveryRescheduled, DeliveryHeadedToDropoff e DeliveryCompleted.
Observe que esses eventos descrevem itens que são significativos no modelo de domínio. Eles descrevem algo sobre o domínio e não estão ligados a um constructo de linguagem de programação específico.
A equipe de desenvolvimento identificou mais uma área de funcionalidade que não se adéqua a nenhuma das entidades descritas até agora. Alguma parte do sistema precisa coordenar todas as etapas envolvidas no agendamento ou na atualização de uma entrega. A equipe de desenvolvimento adicionou dois serviços de domínio ao design. Um agendador coordena as etapas. Um Supervisor monitora o status de cada etapa para detectar se alguma das etapas falhou ou atingiu o tempo limite.
Identificar microsserviços
Agora estamos prontos para passar do modelo de domínio para o design do aplicativo. Veja uma abordagem que você pode usar para derivar os microsserviços do modelo de domínio.
- Comece com um contexto limitado. Em geral, a funcionalidade em um microsserviço não deve abranger mais de um contexto limitado. Por definição, um contexto limitado marca o limite de um modelo de domínio específico. Se o microsserviço combina modelos de domínio diferentes, é um sinal de que talvez seja necessário refinar sua análise de domínio.
- Em seguida, examine os agregados no seu modelo de domínio. Agregados são, frequentemente, bons candidatos a microsserviços. Uma agregação bem projetada exibe muitas das características de um microsserviço bem projetado:
- Agregações são derivadas de requisitos empresariais, e não de questões técnicas, tais como acesso a dados ou mensagens.
- Uma agregação deve ter alta coesão funcional.
- Uma agregação é um limite de persistência.
- As agregações devem ser livremente acopladas.
- Serviços de domínio sempre são bons candidatos a microsserviços. Os serviços de domínio são operações sem estado em várias agregações. Um exemplo típico é um fluxo de trabalho que envolve vários microsserviços. Mais tarde, veremos um exemplo de um serviço de domínio no aplicativo Entrega por Drone.
- Por fim, considere os requisitos não funcionais. Observe fatores como tamanho da equipe, tipos de dados, tecnologias, requisitos de escalabilidade, requisitos de disponibilidade e requisitos de segurança. Esses fatores podem levar você a decompor ainda mais um microsserviço em dois (ou mais) serviços menores ou a fazer o contrário e combinar vários microsserviços em um.
É importante ser pragmático e lembrar-se de que o design orientado por domínio é um processo iterativo. Em caso de dúvida, comece com microsserviços de granulação grosseira. É mais fácil dividir um microsserviço em dois serviços menores do que refatorar a funcionalidade em vários microsserviços existentes.
Aplicar o design controlado por domínio ao aplicativo de drone
Para o aplicativo da Fabrikam, todos esses serviços residem no aplicativo monolítico existente. Depois de identificar como é possível decompor seu aplicativo em microsserviços, o serviço de pacote será iniciado.
No momento, o serviço de pacotes tem uma equipe de desenvolvimento dedicada, está apresentando problemas de desempenho relacionados à escalabilidade e é um ótimo candidato à decomposição do aplicativo.