O design orientado por domínio (DDD) se opõe à ideia de ter um único modelo unificado para todo o sistema; em vez disso, incentiva a divisão do sistema em contextos limitados, cada um dos quais tem seu próprio modelo. Durante a fase estratégica de DDD, você está mapeando fora do domínio empresarial e definindo 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, em que cada contexto limitado é um candidato a microsserviço, estamos particularmente interessados nos padrões de entidade e agregação. Aplicar esses padrões nos ajudará a identificar limites naturais para os serviços em nosso aplicativo (consulte o próximo artigo desta série). 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. Primeiro, examinaremos os padrões táticos. Em seguida, os aplicaremos ao contexto limitado de remessa no aplicativo de entrega por drones.
Esta seção fornece um breve resumo sobre os padrões táticos de DDD, portanto, se você já está familiarizado com DDD, provavelmente, pode ignorar esta seção. Os padrões são descritos mais detalhadamente nos capítulos 5 e 6 do livro Implementing Domain-Driven Design de Vaughn Vernon.
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 seriam entidades.
- Uma entidade tem um identificador exclusivo no sistema, que pode ser usado para pesquisar pela entidade ou recuperá-la. Isso não significa que o identificador é sempre exposto diretamente aos usuários. Ele pode ser um GUID ou uma chave primária em um banco de dados.
- Uma identidade pode abranger vários contextos limitados e pode durar mais que o tempo de vida do aplicativo. Por exemplo, números de conta bancária ou IDs emitidas pelo governo não estão vinculados ao tempo de vida de um aplicativo específico.
- Os atributos de uma entidade podem se alterar ao longo do tempo. Por exemplo, o nome ou endereço de uma pessoa pode ser alterado, mas ela ainda é a mesma pessoa.
- Uma entidade pode conter referências a outras entidades.
Objetos de valor. Um objeto de valor não tem identidade. Ele é definido somente pelos valores de seus atributos. Objetos de valor também são imutáveis. Para atualizar um objeto de valor, você sempre cria uma nova instância para substituir a antiga. Objetos de valor podem ter métodos que encapsulam a lógica do domínio, mas esses métodos não devem ter efeitos colaterais sobre o estado do objeto. 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. Exatamente uma entidade em uma agregação é a raiz. A pesquisa é feita usando o identificador da entidade raiz. Quaisquer outras entidades na agregação são filhas da raiz e são referenciadas da raiz pelos ponteiros a seguir.
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?
Aplicativos tradicionais têm usado frequentemente transações de banco de dados para impor a consistência. Em um aplicativo distribuído, no entanto, isso muitas vezes não é viável. Uma única transação empresarial pode abranger vários repositórios de dados, ser demorada ou envolver serviços de terceiros. Por fim, cabe ao aplicativo, não à camada de dados, impor as invariáveis necessárias para o domínio. É isso que as agregações destinam-se a modelar.
Observação
Um agregado pode consistir em uma única entidade, sem entidades filho. O que compõe uma agregação é o limite transacional.
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 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.
Observação
O termo serviço está sobrecarregado no desenvolvimento de software. Aqui a definição não está diretamente relacionada a microsserviços.
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. O artigo Comunicação entre serviços discute mensagens assíncronas em mais detalhes.
Há alguns outros padrões de DDD não listados aqui, incluindo módulos, repositórios e fábricas. Eles poderão ser padrões úteis para quando você estiver implementando um microsserviço, mas eles são menos relevantes ao projetar os limites entre microsserviços.
Começaremos com os cenários com os quais o contexto limitado de remessa deve lidar.
- Um cliente pode solicitar que um drone colete os produtos de uma empresa que está registrada com o serviço de entrega por drones.
- O remetente gera uma marcação (código de barras ou RFID) para colocar no pacote.
- Um drone coletará um pacote no local de origem e o entregará no local de destino.
- Quando um cliente agenda uma entrega, o sistema fornece um ETA com base em informações de rota, condições climáticas e dados históricos.
- Quando o drone está em trânsito, um usuário pode acompanhar a localização atual e a ETA mais recente.
- Até que um drone tenha coletado o pacote, o cliente pode cancelar uma entrega.
- O cliente é notificado quando a entrega é concluída.
- O remetente pode solicitar confirmação de entrega do cliente, na forma de uma assinatura ou impressão digital.
- Os usuários podem pesquisar o histórico de uma entrega concluída.
Desses cenários, a equipe de desenvolvimento identificou as entidades a seguir.
- Entrega
- Pacote
- Drone
- Conta
- Confirmação
- Notificação
- Marca
Os quatro primeiros, entrega, pacote, drone e conta, são todos agregações que representam limites de consistência transacional. Confirmações e Notificações são entidades filho de Entregas e Tags são entidades filho de Pacotes.
Os objetos de valor neste projeto incluem Localização, ETA, PackageWeight e PackageSize.
Para ilustrar, aqui está um diagrama UML da agregação de Entrega. Observe que ele contém referências a outras agregações, incluindo Conta, Pacote e Drone.
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 seu status (em curso, descarregou).
A entidade Entrega envia eventos DeliveryTracking sempre que o estágio de uma entrega é alterado. Isso inclui 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. Portanto, a equipe de desenvolvimento adicionou dois serviços de domínio ao design: um Scheduler que coordena as etapas e um Supervisor que monitora o status de cada etapa para detectar se alguma etapas falhou ou atingiu o tempo limite. Essa é uma variação do padrão Supervisor de Agente de Agendador.
A próxima etapa é definir os limites para cada microsserviço.