Como usar DDD tático para criar microsserviços
O DDD (design controlado pelo domínio) 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 com seu próprio modelo. Durante a fase estratégica do DDD, você mapeia o domínio de negócios 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, em que cada contexto delimitado é um candidato a microsserviço, a entidade e os padrões de agregação são importantes. A aplicação desses padrões ajuda a identificar limites naturais para os serviços em seu aplicativo. Para obter mais informações, consulte Identificar limites de microsserviço. Como princípio geral, um microsserviço não deve ser menor que uma agregação e não maior que um contexto limitado.
Este artigo analisa os padrões táticos e, em seguida, aplica-os ao contexto de envio limitado no aplicativo de Entrega de Drones.
Visão geral dos padrões táticos
Esta seção fornece um breve resumo dos padrões Táticos de DDD. Se você estiver familiarizado com o DDD, talvez opte por ignorá-lo. Esses padrões são descritos com mais detalhes nos capítulos 5 e 6 do livro de Eric Evans, e em Implementando Domain-Driven Design por 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 persistir além do tempo de vida do aplicativo. Por exemplo, números de conta bancária ou IDs emitidas pelo governo não estão vinculados a um aplicativo específico.
Os atributos de uma entidade podem ser alterados ao longo do tempo. Por exemplo, o nome ou o endereço de uma pessoa pode mudar, mas eles permanecem o mesmo indivíduo.
Objetos de valor. Um objeto de valor não tem identidade. Ele é definido apenas pelos valores de seus atributos. Objetos de valor são imutáveis. Para atualizar um objeto de valor, uma nova instância é criada para substituir a antiga. Objetos de valor podem incluir métodos que encapsulam a lógica de domínio, mas esses métodos não devem produzir efeitos colaterais ou modificar o estado do objeto. Exemplos comuns de objetos de valor incluem cores, datas e horas e valores de moeda.
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. A definição usada aqui não está diretamente relacionada a microsserviços.
Eventos de domínio. Os eventos de domínio podem notificar outras partes do sistema quando algo ocorre. Como o nome sugere, os eventos de domínio devem representar algo significativo 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 importantes em uma arquitetura de microsserviços. Como os microsserviços são distribuídos e não compartilham armazenamentos de dados, os eventos de domínio permitem a coordenação entre os serviços. Para obter mais informações sobre mensagens assíncronas, consulte Comunicação entre serviços.
Há alguns outros padrões de DDD não abordados aqui, incluindo fábricas, repositórios e módulos. Esses padrões podem ser úteis quando você implementa um microsserviço, mas eles são menos relevantes quando você projeta os limites entre microsserviços.
Entrega por drones: aplicando os padrões
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
- Zangão
- 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. Os eventos DeliveryTracking 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. Portanto, a equipe de desenvolvimento adicionou dois serviços de domínio ao design: um Agendador que coordena as etapas e um Supervisor que monitora o status de cada etapa, a fim de detectar se alguma etapa falhou ou atingiu o tempo limite. Essa abordagem é uma variação do padrão supervisor do Agente de Agendador.
Próximas etapas
A próxima etapa é definir os limites para cada microsserviço.