Estou aprendendo DDD e ainda tenho mais perguntas do que respostas.
Vamos considerar um modelo de diretório que contém um número enorme de arquivos.
Aqui está como eu o vejo:
O diretório é uma raiz agregada.
Essa entidade deve ter a lógica de validação para verificar a exclusividade do nome do arquivo quando ele é adicionado ou apenas renomeado. E a entidade File contém a lógica 'SetName', notificando o Diretório via Evento de Domínio sobre alterações de nome.
Mas como o Directory deve funcionar?
Nem sempre é possível carregar todos os arquivos na memória. Nesse caso, o repositório de arquivos deve ter uma lógica adhoc para verificar a exclusividade do nome? Suponho que é uma decisão viável.
No entanto, e se alguns arquivos já tiverem sido adicionados ou renomeados na transação atual ainda não confirmada? (nada proíbe isso. Os limites da transação são definidos externamente em relação à lógica de negócios). Provavelmente, o repositório deve levar em consideração os estados persistentes e na memória (mesclar esses estados pode ser uma tarefa não trivial).
Então, quando a raiz agregada com todos os seus filhos se encaixa na memória - está tudo bem. E assim que você não puder materializar todas as entidades, haverá problemas.
Eu gostaria de saber quais são as abordagens para essas situações. Pode não haver nenhum problema e é apenas por causa do meu mal-entendido sobre o assunto.
fonte
Respostas:
Minha resposta é tendenciosa com o grande livro Implementing Domain Driven Design de Vaughn Vernon (uma leitura obrigatória)
1. Favorecer agregados pequenos.
Se eu quiser modelar seu domínio, eu modelaria a
Directory
como um agregado eFile
como outro agregado.2. Agregados de referência por IDs.
Portanto
Directory
, terá uma coleção deFileId
objetos de valor.3. Use fábricas para criar agregados.
Para um caso simples, um método de fábrica pode ser suficiente
Directory.addFile(FileName fileName)
. No entanto, para casos mais complexos, eu usaria uma fábrica de domínio.A fábrica de domínio pode validar que
fileName
é exclusivo usando umFileRepository
e umUniquefileNameValidator
serviço de infraestrutura.Por que modelar
File
como um agregado separado?Porque
Directories
não são feitosFiles
. aFile
está associado a um certoDirectory
. Além disso, pense em um diretório que possui milhares de arquivos. Carregar todos esses objetos na memória toda vez que um diretório é buscado é um fator que prejudica o desempenho.Modele seus agregados de acordo com seus casos de uso. Se você souber que nunca haverá mais do que 2-3 arquivos em um diretório, poderá modelá-los todos como um único agregado, mas, na minha experiência, as regras de negócios mudam o tempo todo e vale a pena se o seu modelo for flexível o suficiente para acomodar o alterar.
Leitura obrigatória Design agregado eficaz por Vaughn Vernon
fonte
inode
sistemas Unix.File
com determinado Nome pode existirDirectory
, ou seja,Directory
possui a invariante: Exclusividade do Nome. Pelo menos é importante para oDirectory
, mas não para oFile
. Na verdade, @AlexanderLanger está certo: 'Arquivo' pode ser referenciado por muitas 'Pastas'. E o nome é provavelmente a propriedade dessa referência e não aFile
si mesma. Está bem. A renomeação da funcionalidade pertence aoDirectory
, mas, novamente, não é uma boa ideia armazenar milhares de identidades referenciadas.bool ContainsFileOfName(int folderId, string fileName)
. Depois disso, a assinatura do método 'Renomear' pode ser a seguinte:void Rename(int fileId, string newName)
onde dentro de algunsIFolderService
(que repositório envolve) é resolvido e perguntado se esse nome existe.Esta não é uma pergunta DDD propriamente dita. A principal questão aqui é sobre o contexto de sincronização (que é aqui uma raiz agregada).
Voltar ao tópico: O diretório deve bloquear algum objeto de sincronização dos nomes dos arquivos e verificar se o nome do arquivo fornecido é permitido, o que é O (n) no pior caso.
fonte
Embora alguns possam dizer que tentam alterar seu design, sempre há uma necessidade de um AR ter uma grande lista de objetos simples. E armazená-los na memória não é a melhor coisa a fazer da perspectiva do desempenho, no entanto, tudo o que você precisa fazer nesses casos é preservar os limites da transação. Uma solução simples é a seguinte:
Algumas restrições:
fonte