No design orientado a domínio, como converter uma tabela de banco de dados com uma chave primária em um objeto de valor?

8

Vamos supor que exista um esquema de banco de dados definido assim:

Person.mail_address_key ----- Address.address_key
Person.billing_address_key ----- Address.address_key

A Persontem um endereço para correspondência e um endereço para cobrança. Como uma técnica de desnormalização, criamos uma Addresstabela separada . Na maioria das vezes, o mail_address_keye o billing_address_keyde um único Personterão o mesmo valor (ou seja: a chave do endereço de correspondência e cobrança será a mesma).

Na minha banco de dados do Addresstem uma identidade (a chave de endereço). Mas, no meu modelo de domínio , não vejo uma razão convincente para Addressque seja uma Entidade, gostaria que fosse um Objeto de Valor.

  1. No DDD, isso é uma opção? Ou os objetos de valor geralmente são um grupo de colunas (em oposição a uma tabela)? Estou meio que defendendo o advogado do diabo aqui, porque acho que o banco de dados não deve ditar a estrutura do modelo de domínio, mas apenas assegurando.
  2. Em caso afirmativo, onde / quando / como o endereço perde sua identidade do banco de dados para que possa ser usado como um Objeto de Valor na Camada de Domínio? Ou, devo manter o identificador do banco de dados no objeto de valor?
  3. Quando o modelo precisa ser persistido no banco de dados, qual é o processo? Devo passar por um processo de a) Encontre um endereço por esses campos, b) se ele não existir, crie um novo c) se houver, atualize os campos?
Daniel Kaplan
fonte
Tornar um endereço de email um objeto de valor utilizável pode ser muito difícil, porque testar endereços de email para igualdade não é tão fácil e provavelmente testar endereços postais também não é.
SpaceTrucker
@ SpaceTrucker Acho que não li nada que diga que deve levar em consideração sua decisão de transformar um modelo em um objeto de valor.
Daniel Kaplan

Respostas:

2

No DDD, isso é uma opção? Ou os objetos de valor geralmente são um grupo de colunas (em oposição a uma tabela)? Estou meio que defendendo o advogado do diabo aqui, porque acho que o banco de dados não deve ditar a estrutura do modelo de domínio, mas apenas assegurando.

O banco de dados não deve ditar a estrutura do modelo de domínio, para que você esteja certo. Os objetos de valor podem ser armazenados no banco de dados como uma coluna ou tabela, dependendo do tipo de dados que o objeto de valor deve transportar.

Em caso afirmativo, onde / quando / como o endereço perde sua identidade do banco de dados para que possa ser usado como um Objeto de Valor na Camada de Domínio? Ou, devo manter o identificador do banco de dados no objeto de valor?

Seu código de domínio não deve estar repleto de propriedades que são para outras preocupações, como persistência, pois devem ser completamente ignorantes. Você realmente deve se concentrar na sua raiz agregada. Você deve ter alguma maneira de identificar sua raiz agregada ao salvá-la no banco de dados; nesse momento, você só precisará verificar o registro da tabela Person (presumo que Person seja sua raiz agregada) e ver se há um valor no campo MailingAddressID ou BillingAddressID. Nesse ponto, você pode decidir se deseja criar novos endereços e alterar os links para apontar para os novos endereços ou substituir os endereços que já estão vinculados.

Quando o modelo precisa ser persistido no banco de dados, qual é o processo? Devo passar por um processo de a) Encontre um endereço por esses campos, b) se ele não existir, crie um novo c) se houver, atualize os campos?

Como expliquei um pouco na resposta acima, você deve hidratar e desidratar seu gráfico de objetos com base em sua raiz agregada. Portanto, quando seu repositório obtém sua raiz agregada do banco de dados, ele também hidrata todas as entidades e objetos de valor necessários em sua raiz agregada, associados à sua raiz agregada no banco de dados. O mesmo acontece quando você salva a raiz agregada novamente no banco de dados. Seu repositório deve ser capaz de manipular todo o gráfico de objetos na raiz agregada.

Aaron Hawkins
fonte
Ah, isso faz muito sentido. Obrigado pela ajuda.
Daniel Kaplan
2

O DDD não aplica o esquema do banco de dados. O objeto de valor pode ser implementado como um grupo de colunas, entidade db (sua terceira solução) ou simplesmente em uma forma desnormalizada, se você puder usar o banco de dados orientado a documentos, por exemplo. Depende de diferentes circunstâncias, qual é a melhor opção para ir.

Lembre-se de que o banco de dados é apenas uma ferramenta para persistir o estado do seu domínio. Não deve forçar nenhuma decisão de design. Se, por algum motivo, você precisar usar a identidade para a representação do objeto de valor no DB, faça isso, mas não derrame esses detalhes de implementação no próprio domínio. Crie um wrapper / estenda classes de domínio / o que sua estrutura permitir e inclua o ID em uma classe de infraestrutura completamente separada, permitindo que o aplicativo / estrutura persista o estado.

Mequrel
fonte
Você pode mostrar algumas implementações concretas (pode ser pseudo-código)?
Daniel Kaplan
-1

Não vejo nenhum requisito especial do DDD nesse caso. Você pode modelar endereços de correspondência e cobrança como propriedades de uma pessoa e ainda armazená-los em uma tabela separada, por exemplo:

Person
+ MailingAddress : Address
+ BillingAddress : Address

ou

Person
+ MailingAddressID
+ MailingAddress : Address
+ BillingAddressID
+ BillingAddress : Address
Tien Do
fonte
1
Eu não sinto que este é responder a todas (ou mesmo a maioria) das minhas perguntas
Daniel Kaplan