Aplique invariantes abrangendo várias agregações (validação de conjunto) no Design orientado a domínio

Para ilustrar o problema, usamos um caso simples: existem dois agregados -Lamp eSocket. A regra de negócios a seguir sempre deve ser imposta: nem umLamp nem umSocket pode ser conectado mais de uma vez ao mesmo tempo. Para fornecer um comando apropriado, concebemos umConnector-serviço com oConnect(Lamp, Socket)método para conectá-los.

Como queremos cumprir a regra de que uma transação deve envolver apenas um agregado, não é aconselhável definir a associação nos dois agregados noConnect-transação. Portanto, precisamos de um agregado intermediário que simbolize oConnection em si. Então oConnect-transaction criaria apenas um novoConnection com os componentes fornecidos. Infelizmente, neste ponto os problemas começam; como podemos garantir a consistência do estado da conexão? Pode acontecer que muitos usuários simultâneos desejem conectar os mesmos componentes ao mesmo tempo, para que nossa "verificação de consistência" não rejeite a solicitação. NovoConnection-aggregates seriam armazenados, porque bloqueamos apenas no nível agregado. O sistema seria inconsistente sem ao menos saber disso.

Mas como devemos definir o limite de nossos agregados para garantir nossa regra de negócios? Poderíamos conceber umaConnections-gregate que reúne todas as conexões ativas (comoConnection-entity), possibilitando assim nosso algoritmo de bloqueio que rejeitaria corretamente duplicadosConnect-solicitações de. Por outro lado, essa abordagem é ineficiente e não é escalável; além disso, é contra-intuitiva em termos de linguagem de domínio.

Você sabe o que estou perdendo?

Editar: Para resumir o problema, imagine um agregadoUser. Como a definição de um agregado deve ser uma unidade baseada em transações, podemos aplicar invariantes bloqueando essa unidade por transação. Está tudo bem. Mas agora surge uma regra de negócios: o nome de usuário deve ser exclusivo. Portanto, devemos de alguma forma reconciliar nossos limites agregados com esse novo requisito. Supondo que milhões de usuários se registrem ao mesmo tempo, isso se torna um problema. Tentamos garantir isso invariável em um estado não bloqueado, pois vários usuários significam vários agregados.

De acordo com o livro "Design Orientado a Domínio" de Eric Evans, deve-se aplicar consistência eventual assim que vários agregados estiverem envolvidos em uma única transação. Mas este é realmente o caso aqui e faz sentido?

A aplicação de eventual consistência aqui implicaria o registro doUser e depois verificando o invariante com o nome de usuário. Se doisUsers realmente definem o mesmo nome de usuário, o sistema desfaz o segundo registro e notifica oUser. Pensar nesse cenário me incomoda, porque atrapalha todo o processo de registro. O envio do e-mail de confirmação, por exemplo, teve que ser adiado e assim por diante.

Acho que estou esquecendo algo em geral, mas não sei o quê. Parece-me que preciso de algo como invariantes emRepository-nível.

questionAnswers(3)

yourAnswerToTheQuestion