Aqui está um pequeno problema
Tenha uma entidade, com um objeto de valor. Não é um problema. Substituo um objeto de valor por um novo e, em seguida, o nhibernate insere o novo valor e torna-o órfão, excluindo-o. Ok, isso é um problema.
Segurado é minha entidade em meu domínio. Ele tem uma coleção de endereços (objetos de valor). Um dos endereços é o MailingAddress. Quando queremos atualizar o endereço de correspondência, digamos que o CEP esteja errado, seguindo a doutrina do Sr. Evans, devemos substituir o objeto antigo por um novo, uma vez que é imutável (um objeto de valor, certo?).
Mas não queremos excluir a linha, porque o PK desse endereço é um FK em uma tabela MailingHistory. Então, seguindo a doutrina do Sr. Evans, estamos praticamente ferrados aqui. A menos que eu faça minhas entidades de endereços, não preciso "substituí-la" e simplesmente atualizar seu membro do CEP, como nos bons e velhos tempos.
O que você me sugeriria neste caso? Do meu ponto de vista, os ValueObjects são úteis apenas quando você deseja encapsular um grupo de colunas da tabela de banco de dados (componente no nhibernate). Tudo o que tem um ID de persistência no banco de dados é melhor para torná-lo uma Entidade (não necessariamente uma raiz agregada) para que você possa atualizar seus membros sem recriar todo o gráfico de objetos, especialmente se esse for um objeto profundamente aninhado.
Você concorda? Evans tem permissão para ter um objeto de valor mutável? Ou um objeto de valor mutável é candidato a uma Entidade?
obrigado
fonte
Respostas:
Tudo o que tem uma identidade deve ser uma Entidade, e tudo o que não tem uma identidade é um valor simples, portanto, um objeto de valor.
Para citar Martin Fowler (que por sua vez cita Eric Evans)
Razão para tornar seu endereço um objeto de valor:
Se o seu endereço for mutável, você provavelmente irá estragar seu histórico de correspondência no final. Por exemplo, se você estiver enviando itens para um cliente, não pode ter certeza de qual endereço realmente enviou algo no passado, se o endereço ao qual sua tabela MailingHistory se refere foi alterado.
A entrada MailingHistory Enviamos o A764 para o endereço 657 pode significar Enviamos o artigo A764 para Boston ontem e enviámos o artigo A764 para Nova York amanhã.
Se o endereço de correspondência tiver sido alterado, não será necessário excluir o antigo. Mantenha-o e marque-o como inativo , e o novo como ativo .
É claro que você poderia tratar seu endereço como uma Entidade, mas somente ao atualizá-lo não mudaria o local real ao qual o endereço está se referindo, portanto, permitindo apenas a correção de erros de digitação.
Se você tem certeza de que pode garantir isso, seria possível usar uma Entidade.
Mas a melhor solução IMHO é não referenciar uma entidade de endereço no seu histórico de correspondência, mas salvar o endereço específico diretamente na sua tabela de histórico de correspondência (basicamente copiando os dados do endereço).
Dessa forma, você sempre sabe para onde enviou suas coisas (ou o que quer que esteja enviando) e, como usaria uma Entidade mutável, sua tabela de endereços não ficará desordenada.
Eu trabalhei com / em vários sistemas ERP e quase todos eles usaram essa abordagem.
Você terá alguma redundância em seu banco de dados, mas é a maneira mais pragmática do IMHO.
fonte
ALTER
, o uso de entidades em tabelas separadas poderá se tornar necessário. Isso, por sua vez, exige estratégias como "sempre associe o endereço / telefone / e-mail mais recentes " nas suasSELECT
consultas, o que é difícil manter a manutenção e a eficiência. Mantenha-o simples, se possível.active
sinalizador-. É claro que você deve sempre usarand active = true
suas Joins, manter o sinalizador atualizado e adicionar uma contraint à sua tabela para que, por exemplo, apenas um e-mail para cada cliente possa ter esse sinalizador definido como verdadeiro.active=true
. Não é isso que eu chamaria de simples, e é exatamente por isso que gosto da sua solução.Eu vejo duas coisas:
Está correto a alteração do código postal afetar um registro do histórico? Eu acho que seria lógico que o registro do histórico aponte para o endereço antigo e inalterado, para que você o envie para o endereço errado.
No momento em que MailingHistory tem FK no endereço, o endereço deixou de ser um objeto de valor e se tornou entidade. Objetos de valor não têm identidade, permitindo que outras entidades façam referência a essa identidade. Você pode ter endereços em uma única tabela com outras tabelas apontando para ela, mas o único efeito é a economia de espaço. Do ponto de vista do domínio, se duas entidades tiverem o mesmo tipo de objeto de valor de referência, elas não compartilharão nenhum tipo de informação.
fonte
OMI, o objeto de endereço é uma entidade em seu domínio. É compartilhado por várias entidades, possui identidade própria e é exclusivo em todo o sistema.
Evans diz:
fonte