Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Dica
Esse conteúdo é um trecho do eBook, arquitetura de microsserviços do .NET para aplicativos .NET em contêineres, disponível em do .NET Docs ou como um PDF para download gratuito que pode ser lido offline.
Defina um modelo de domínio avançado para cada microsserviço de negócios ou Contexto Limitado.
Sua meta é criar um único modelo de domínio coeso para cada microsserviço de negócios ou Contexto Delimitado (BC). No entanto, tenha em mente que um microsserviço de BC ou de continuidade de negócios, às vezes, pode ser composto por vários serviços físicos que compartilham um único modelo de domínio. O modelo de domínio deve capturar as regras, o comportamento, a linguagem de negócios e as restrições do único contexto limitado ou microsserviço empresarial que ele representa.
O padrão de entidade do domínio
As entidades representam objetos de domínio e são definidas principalmente por sua identidade, continuidade e persistência ao longo do tempo, e não apenas pelos atributos que os compõem. Como diz Eric Evans, "um objeto definido principalmente por sua identidade é chamado de Entidade". As entidades são muito importantes no modelo de domínio, pois são a base para um modelo. Portanto, você deve identificá-los e projetá-los cuidadosamente.
A identidade de uma entidade pode cruzar vários microsserviços ou Contextos Limitados.
A mesma identidade (ou seja, o mesmo Id valor, embora talvez não seja a mesma entidade de domínio) pode ser modelada em vários Contextos Limitados ou microsserviços. No entanto, isso não implica que a mesma entidade, com os mesmos atributos e lógica, seria implementada em vários Contextos Limitados. Em vez disso, as entidades em cada Contexto Limitado limitam seus atributos e comportamentos aos necessários no domínio desse Contexto Limitado.
Por exemplo, a entidade compradora pode ter a maioria dos atributos de uma pessoa definidos na entidade de usuário no microsserviço de perfil ou identidade, incluindo a identidade. Mas a entidade compradora no microsserviço de pedidos pode ter menos atributos, pois apenas determinados dados do comprador estão relacionados ao processo de pedido. O contexto de cada microsserviço ou contexto limitado afeta seu modelo de domínio.
As entidades de domínio devem implementar o comportamento além de implementar atributos de dados.
Uma entidade de domínio no DDD deve implementar a lógica de domínio ou o comportamento relacionado aos dados da entidade (o objeto acessado na memória). Por exemplo, como parte de uma classe de entidade de ordem, você deve ter a lógica de negócios e as operações implementadas como métodos para tarefas como a adição de um item de pedido, validação de dados e cálculo total. Os métodos da entidade cuidam dos invariáveis e das regras da entidade em vez de ter essas regras espalhadas pela camada do aplicativo.
A Figura 7-8 mostra uma entidade de domínio que implementa não apenas atributos de dados, mas operações ou métodos com lógica de domínio relacionada.
Figura 7-8. Exemplo de um design de entidade de domínio implementando dados mais comportamento
Uma entidade de modelo de domínio implementa comportamentos por meio de métodos, ou seja, não é um modelo "anêmico". É claro que, às vezes, você pode ter entidades que não implementam nenhuma lógica como parte da classe de entidade. Isso pode acontecer em entidades filho dentro de uma agregação se a entidade filho não tiver nenhuma lógica especial porque a maior parte da lógica é definida na raiz de agregação. Se você tiver um microsserviço complexo que tenha a lógica implementada nas classes de serviço em vez de nas entidades de domínio, poderá estar caindo no modelo de domínio anêmico, explicado na seção a seguir.
Modelo de domínio avançado versus modelo de domínio anêmico
Em seu post AnemicDomainModel, Martin Fowler descreve um modelo de domínio anêmico desta maneira:
O sintoma básico de um modelo de domínio anêmico é que, à primeira vista, ele parece real. Existem objetos, muitos nomeados de acordo com os nomes no espaço de domínio, conectados com as relações avançadas e a estrutura que os modelos de domínio verdadeiros têm. A verdade aparece quando você observa o comportamento e percebe que não há praticamente nenhum comportamento nesses objetos, ou seja, eles não passam de pacotes de getters e setters.
Claro, quando você usa um modelo de domínio anêmico, esses modelos de dados serão usados de um conjunto de objetos de serviço (tradicionalmente chamado de camada de negócios) que capturam todo o domínio ou lógica de negócios. A camada de negócios fica acima do modelo de dados e usa o modelo de dados apenas como dados.
O modelo de domínio anêmico é apenas um design de estilo de procedimento. Objetos de entidade anêmica não são objetos reais porque não têm comportamento (métodos). Elas contêm apenas propriedades de dados e, portanto, não são design orientado a objetos. Colocando todo o comportamento em objetos de serviço (a camada de negócios), você essencialmente acaba com scripts de transação ou código de espaguete e, portanto, você perde as vantagens que um modelo de domínio fornece.
Independentemente disso, se seu microsserviço ou Contexto Limitado for muito simples (um serviço CRUD), o modelo de domínio anêmico na forma de objetos de entidade com apenas propriedades de dados poderá ser bom o suficiente e talvez não valha a pena implementar padrões de DDD mais complexos. Nesse caso, será simplesmente um modelo de persistência, pois você criou intencionalmente uma entidade com apenas dados para fins CRUD.
É por isso que as arquiteturas de microsserviços são perfeitas para uma abordagem multi-arquitetural, dependendo de cada contexto delimitado. Por exemplo, no eShopOnContainers, o microsserviço de ordenação implementa padrões DDD, mas o microsserviço de catálogo, que é um serviço CRUD simples, não.
Algumas pessoas dizem que o modelo de domínio anêmico é um antipadrão. Isso realmente depende do que você está implementando. Se o microsserviço que você está criando for simples o suficiente (por exemplo, um serviço CRUD), seguindo o modelo de domínio anêmico, ele não é um antipadrão. No entanto, se você precisar lidar com a complexidade do domínio de um microsserviço que tem muitas regras de negócios em constante mudança, o modelo de domínio anêmico pode ser um antipadrão para esse microsserviço ou Contexto Limitado. Nesse caso, projetá-lo como um modelo avançado com entidades que contêm dados mais comportamento, bem como implementar padrões DDD adicionais (agregações, objetos de valor etc.) pode ter enormes benefícios para o sucesso a longo prazo desse microsserviço.
Recursos adicionais
DevIQ. Entidade de Domínio
https://deviq.com/entity/Martin Fowler. O modelo de domínio
https://martinfowler.com/eaaCatalog/domainModel.htmlMartin Fowler. The Anemic Domain Model (O modelo de domínio anêmico)
https://martinfowler.com/bliki/AnemicDomainModel.html
O padrão de objeto de valor
Como Eric Evans observou: "Muitos objetos não têm identidade conceitual. Esses objetos descrevem certas características de uma coisa."
Uma entidade requer uma identidade, mas há muitos objetos em um sistema que não o fazem, como o padrão objeto value. Um objeto de valor é um objeto sem identidade conceitual que descreve um aspecto de domínio. Estes são objetos que você instancia para representar elementos de design que só lhe dizem respeito temporariamente. Você se importa com o que eles são, não quem eles são. Exemplos incluem números e cadeias de caracteres, mas também podem ser conceitos de nível superior, como grupos de atributos.
Algo que é uma entidade em um microsserviço pode não ser uma entidade em outro microsserviço, pois no segundo caso, o Contexto Limitado pode ter um significado diferente. Por exemplo, um endereço em um aplicativo de comércio eletrônico pode não ter uma identidade, pois pode representar apenas um grupo de atributos do perfil do cliente para uma pessoa ou empresa. Nesse caso, o endereço deve ser classificado como um objeto de valor. No entanto, em um aplicativo para uma empresa de energia elétrica, o endereço do cliente pode ser importante para o domínio empresarial. Portanto, o endereço deve ter uma identidade para que o sistema de cobrança possa ser vinculado diretamente ao endereço. Nesse caso, um endereço deve ser classificado como uma entidade de domínio.
Uma pessoa com nome e sobrenome geralmente é uma entidade porque uma pessoa tem identidade, mesmo que o nome e o sobrenome coincidam com outro conjunto de valores, como se esses nomes também se referem a uma pessoa diferente.
Objetos de valor são difíceis de gerenciar em bancos de dados relacionais e ORMs como o Entity Framework (EF), enquanto em bancos de dados orientados a documentos eles são mais fáceis de implementar e usar.
O EF Core 2.0 e versões posteriores incluem o recurso entidades de propriedade que facilita o manipulação de objetos de valor, como veremos em detalhes mais adiante.
Recursos adicionais
Martin Fowler. Padrão de objeto de valor
https://martinfowler.com/bliki/ValueObject.htmlObjeto de Valor
https://deviq.com/value-object/Objetos de valor no desenvolvimento de Test-Driven
https://leanpub.com/tdd-ebook/read#leanpub-auto-value-objectsEric Evans. Domain-Driven Design: Abordando a complexidade no coração do software. (Livro; inclui uma discussão sobre objetos de valor)
https://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215/
O padrão de agregação
Um modelo de domínio contém clusters de diferentes entidades de dados e processos que podem controlar uma área significativa de funcionalidade, como o cumprimento de pedidos ou inventário. Uma unidade DDD mais refinada é a agregação, que descreve um cluster ou grupo de entidades e comportamentos que podem ser tratados como uma unidade coesa.
Normalmente, você define uma agregação com base nas transações necessárias. Um exemplo clássico é uma ordem que também contém uma lista de itens de pedido. Geralmente, um item do pedido será uma entidade. Mas ela será uma entidade filha dentro da agregação de pedido, que também conterá a entidade de pedido como entidade raiz, geralmente chamada de raiz de agregação.
Identificar agregações pode ser difícil. Uma agregação é um grupo de objetos que deve ser consistente em conjunto, mas você não pode simplesmente escolher um grupo de objetos e rotulá-los como uma agregação. Você deve começar com um conceito de domínio e pensar nas entidades usadas nas transações mais comuns relacionadas a esse conceito. Essas entidades que precisam ser transacionalmente consistentes são o que forma uma agregação. Pensar em operações de transação é provavelmente a melhor maneira de identificar agregações.
O padrão de raiz de agregação ou de entidade raiz
Uma agregação é composta por pelo menos uma entidade: a raiz de agregação, também chamada de entidade raiz ou entidade primária. Além disso, ele pode ter várias entidades filho e objetos de valor, com todas as entidades e objetos trabalhando juntos para implementar o comportamento e as transações necessários.
A finalidade de uma raiz de agregação é garantir a consistência da agregação; deve ser o único ponto de entrada para atualizações na agregação por meio de métodos ou operações na classe raiz de agregação. Você deve fazer alterações em entidades dentro da agregação apenas por meio da raiz de agregação. Ela é a proteção da consistência da agregação, considerando todas as invariáveis e as regras de consistência que devem ser obedecidas na agregação. Se você alterar uma entidade filho ou um objeto de valor de forma independente, a raiz de agregação não poderá garantir que a agregação esteja em um estado válido. Isso seria semelhante a uma tabela com um segmento flexível. Manter a consistência é a principal finalidade da raiz agregada.
Na Figura 7-9, veja as agregações de exemplo, como a agregação de comprador, que contém uma única entidade (a raiz de agregação de comprador). A agregação de ordem contém várias entidades e um objeto de valor.
Figura 7-9. Exemplo de agregações com várias entidades ou entidades simples
Um modelo de domínio DDD é composto de agregações, uma agregação pode ter apenas uma entidade ou mais e também pode incluir objetos de valor. Observe que a agregação de comprador poderá ter entidades filhas adicionais, dependendo do domínio, como ocorre no microsserviço de pedidos no aplicativo eShopOnContainers de referência. A Figura 7-9 ilustra apenas um caso em que o comprador tem uma única entidade, como um exemplo de uma agregação que contém apenas uma raiz de agregação.
Para manter a separação de agregações e manter limites claros entre elas, é uma boa prática em um modelo de domínio DDD não permitir a navegação direta entre agregações e ter apenas o campo FK (chave estrangeira), conforme implementado no modelo de domínio de microsserviço Ordering no eShopOnContainers. A entidade de pedido tem apenas um campo de chave estrangeira para o comprador, mas não uma propriedade de navegação do EF Core, conforme é mostrado no código a seguir:
public class Order : Entity, IAggregateRoot
{
private DateTime _orderDate;
public Address Address { get; private set; }
private int? _buyerId; // FK pointing to a different aggregate root
public OrderStatus OrderStatus { get; private set; }
private readonly List<OrderItem> _orderItems;
public IReadOnlyCollection<OrderItem> OrderItems => _orderItems;
// ... Additional code
}
Identificar e trabalhar com agregações requer pesquisa e experiência. Para obter mais informações, consulte a lista de recursos adicionais a seguir.
Recursos adicionais
Vaughn Vernon. Design de Agregação Efetivo – Parte I: Modelando uma única agregação (de https://dddcommunity.org/)
https://dddcommunity.org/wp-content/uploads/files/pdf_articles/Vernon_2011_1.pdfVaughn Vernon. Design de agregação efetivo – Parte II: fazendo agregações funcionarem juntas (de https://dddcommunity.org/)
https://dddcommunity.org/wp-content/uploads/files/pdf_articles/Vernon_2011_2.pdfVaughn Vernon. Design agregado efetivo – parte III: obtendo insights por meio da descoberta (de https://dddcommunity.org/)
https://dddcommunity.org/wp-content/uploads/files/pdf_articles/Vernon_2011_3.pdfChris Richardson. Desenvolvendo microsserviços transacionais usando agregações
https://www.infoq.com/articles/microservices-aggregates-events-cqrs-part-1-richardsonDevIQ. O padrão de agregação
https://deviq.com/aggregate-pattern/