DDD: questão raiz agregado
-
16-09-2019 - |
Pergunta
Vamos dizer que eu tenho 2 entidades - Foo e Bar. Foo é uma raiz agregada e contém Bar. Tanto quanto eu entendo, ele deve ser parecido com isto:
public class Foo{
private readonly Bar Bar;
}
Eu quero fornecer funcionalidade para os usuários a escolher Barras para Foos de uma lista definida (e alterá-lo).
Se repositórios são suposto ser para raízes agregadas só isso significa que não haverá nenhum repositório para entidade Bar.
Isto leva a problemas - Bar não pode ser criado / atualizado de forma independente, sem uma referência ao Foo.
Isso significa que Bar é suposto ter um repositório apesar disso, não tem sentido sem um Foo?
Solução
Se você quiser selecionar a partir de uma lista de bares onde eles não estão associados com Foo, então esta não é uma raiz agregada. Por exemplo, você não pode obter a lista de OrderItems sem a sua Ordem, por isso esta é única raiz agregada (Ordem), mas você pode obter a lista de produtos para atribuir a OrderItems, então O produto não é parte da raiz agregada ordem.
Observe que, enquanto OrderItem faz parte da Ordem raiz agregada, você ainda pode criar e atualizar de forma independente. Mas, você não pode obtê-lo sem referência a ordem. Mesmo para o seu Bar, mesmo que fosse parte de Foo, você poderia começar cada (Foo.Bars) e trabalhar com ele, ou fazer Foo.AddBar (novo Bar ()). Mas se você precisa para obter Lista sem Foo, Bar não faz parte do Foo agregada. É uma entidade separada.
Bem, é assim que eu vejo DDD aqui, mas eu não sou Eric Evans, é claro.
Outras dicas
As razões para ter raízes agregadas são:
- Eles fornecem controlada e dirigida acesso a entidades compostas
- Eles podem impor regras para assegurar que todo o agregado é válido
Minha opinião:
Se você precisa selecionar objetos Bar
sem Foo
, use uma BarRepository
.
Mas ...
E se você atualizar um Bar
, e ele quebra uma regra de validação para ele é Foo
pai? Se isso pode acontecer, você deve acessar Bar
via-o de Foo
pai.
Se, no entanto, você precisa acessar um monte de objetos Bar
(por exemplo, para um trabalho em lotes ou relatório), e você sei que Foos
não vai ficar quebrado, vá em frente e acessá-los via BarRepository
.
Lembre-se que as raízes de agregação pode ser composta de outras raízes agregadas. Você pode descobrir que Bar
é uma raiz em si agregada, o que lhe dá justificativa para uma BarRepository
:)
Você tem certeza que Bar necessidade de ser uma entidade? Você tem a necessidade de segui-lo e alterá-lo no domínio? Se você pode olhar para ele como um objeto de valor, gostaria de sugerir que você buscá-lo a partir de um serviço e, em seguida, o objeto de valor "connect" selecionado para a entidade Foo. Por instantes através de uma lista suspensa.