Os clientes podem chamar métodos em entidades diferentes da raiz agregada?

10

Evans introduz em seu livro "Domain Driven Design" no capítulo 6 "Agregados" o conceito de Agregados. Ele define ainda regras para traduzir esse conceito em uma implementação (Evans 2009, pp. 128-129):

A ENTITY raiz pode entregar referências às ENTITIES internas a outros objetos, mas esses objetos podem usá-las apenas de forma transitória e podem não se apegar à referência.

Depois de elaborar outras regras, ele as resume neste parágrafo:

Agrupe as entidades e objetos de valor em agregados e defina limites em torno de cada um. Escolha uma Entidade para ser a raiz de cada Agregado e controle todo o acesso aos objetos dentro do limite através da raiz. Permita que objetos externos mantenham referências apenas à raiz. Referências transitórias a membros internos podem ser distribuídas para uso somente em uma única operação. Como a raiz controla o acesso, ela não pode ser surpreendida por alterações nos internos. Esse arranjo torna prático aplicar todos os invariantes a objetos no agregado e ao agregado como um todo em qualquer alteração de estado.

Então, o que exatamente o uso transitório significa?

Meu colega entende que apenas a raiz agregada expõe uma interface pública para os clientes. Os clientes não terão oportunidade de chamar qualquer operação em uma entidade que não seja a raiz agregada.

Meu entendimento das frases citadas é diferente. Entendo que, de fato, permite explicitamente clientes chamar operações em entidades internas. No entanto, somente após obtê-los da raiz.

Então, vamos dar um exemplo concreto:

Digamos que um Cartconsiste em muitos Items. Cada Itemum tem um Quantity. O modelo deve suportar o caso de uso "Aumentar a quantidade de um item específico". Nenhum invariável pode ser violado, o que afeta algo fora do Item.

Um modelo está violando as regras acima citadas, quando um cliente pode fazer isso chamando cart.item(itemId).increaseQuantity()ou um cliente deve ter permissão para chamar apenas um cart.increaseItemQuantity(itemId)? Qual seria o benefício deste último?

Markus Malkusch
fonte
Qual deles faz mais sentido do ponto de vista comercial?
Robert Harvey
É um exemplo artificial. Minha pergunta é sobre a interpretação dos dois parágrafos citados do livro de Evans. Mas os especialistas no domínio artificial falariam sobre "aumentar a quantidade de um item do carrinho". Portanto, carrinho, item e quantidade fazem parte da UL.
Markus Malkusch
1
Seu exemplo não é mais artificial do que os decretos de Evans. Pode ser útil ressaltar que o DDD não é realmente uma técnica de programação, embora existam muitas pessoas que tentam usá-lo dessa maneira.
Robert Harvey
Você pode compartilhar um pouco mais de texto do livro, para que suas citações sem corpo tenham mais contexto?
Robert Harvey
2
Sim obrigado. O que Evans está dizendo é que você deve permitir que a Raiz Agregada controle seu próprio estado interno (uma boa prática para qualquer classe, na verdade). Portanto, provavelmente faz mais sentido permitir que o carrinho controle a quantidade aumenta cart.increaseItemQuantity(itemId), se por nenhuma outra razão, a menos que seja uma violação da Lei de Deméter. A chamada cart.increaseItemQuantity(itemId)permite que você faça coisas como atualizar os valores totais do carrinho.
Robert Harvey

Respostas:

2

Enquanto Itemnão puder existir sem Cartestar presente, não haverá diferença entre as duas opções. É possível manter invariantes nos dois casos.

No caso de o método estar ativado Item, é Itempossível "notificar" seu carrinho pai para verificar o invariante quando ele precisar alterar seu próprio estado. Isso torna as coisas um pouco mais complicadas, porque existe uma dependência cíclica entre Iteme Cart(o que eu assumo não é um problema, graças à suposição na primeira frase e algo que a IMO precisa existir de qualquer maneira).

No caso de o método estar Cartativado, torna-o mais simples, porque não há necessidade de Itemreferência Cart. Mas isso é complicado porque agora o método não apenas verifica a invariância e o estado muda. Mas também precisa garantir que o item (ou seu ID) seja válido para isso Cart. No outro caso, isso já é tratado pelo método que consulta determinado item do carrinho.

tl; dr; Ambas as opções têm vantagens e desvantagens claras e nenhuma parece ser obviamente melhor ou pior do que outras.

Eufórico
fonte